CPE
102
Winter
2008
Program
4
Due
Date
You must turn
in a functionally correct program to
receive any credit. The grade you receive will be based on
when you turn
it in minus any deductions for the quality of your implementation
and/or multiple
submissions. There is no deduction for the first submission
and a 5%
deduction for each additional submission, if any. Programs
will be
checked for correctness once a day and you will be notified by email if
your
submission is not functionally correct. Programs will be
graded after the
last due date and the results will be emailed to you within a few days
of that
date.
100% (minus
any deductions) by 9:00pm Monday, 2/4/08
90% (minus
any deductions) by 9:00pm Tuesday, 2/5/08
80% (minus
any deductions) by 9:00pm Wednesday, 2/6/08
70% (minus
any deductions) by 9:00pm Thursday, 2/7/08
You must
also turn in a UML Diagram for the
program in lecture on Monday 2/4
– no late diagrams
accepted. The diagram is worth 10% of
your program grade and may
be hand-drawn.
Errata:
None
Objectives
- To
demonstrate basic object-oriented design and development skills.
- I will be
giving you quite a bit of the structure of the solution – use good
judgment “filling in the blanks”.
- To become
more familiar with:
- Java
interfaces and inheritance.
- The concept
of polymorphism.
- The javadoc
style of documenting code.
- Using UML for
designing and describing programs.
Resources
- Java
Standard API
- P4TestDriver.java (Will be published Monday 2/4)
- UML
Overview
- P4UnitTests.zip
Problem
Description
- You will be
creating an inventory
of various products for a fictitious online retailer. You
will develop
the foundation classes and three specific products for use now and to
support
any new products that may be added in the future. These
products will
make use of a utility class to support complex (relatively!) name
searches. In addition, you will be implementing several
methods to find
products by various criteria. You will assign each product a
unique
product identification number. Since the products will have a
quantity
variable you will insure that no duplicates are entered into you
inventory.
Instead, you can manage the number of each product in the inventory by
modifying the quantity instance field.
- JUnit tests will be provided in P4UnitTests.zip.
As in previous assignments, some JUnit test cases are left
stubbed out for you to fill in. In Program 4, you will need to
write JUnit tests for the Inventory, BookOnTape, and CD classes.
Specification
- You must
implement the classes and methods exactly as described or the provided
test driver will not work!
- Document all
public methods in Inventory and
Product classes using the javadoc style of documentation.
Don’t forget the required comment block that belongs at the top of each
and every file too.
- Implement a
class called Inventory.
- With one (and
only one) private instance field of type
ArrayList<Product> to contain products.
- With one
constructor (the default constructor).
- With the
following public methods:
- boolean
addNew(Product product) - Adds the product to the inventory.
This method prevents duplicate products from being added to the
inventory. Duplicates are considered to be products with the
same product ID or products that are equal (based on the equals()
method described below). This method should return true if
the product was successfully added or false the product is a duplicate.
- boolean
addInventory(int productID, int quantity) - Adds the specified quantity
to an existing product in the inventory. Note that the
quantity passed in may be positive or negative. If it is
negative and adding it to the current quantity of the product would
result in a value less that zero the quantity is not changed and false
is returned, otherwise the method returns true.
- ArrayList<Book>
findBooksByAuthor(String last, String first, String middle) – Searches
the Inventory for books by the specified author and returns all matches
in an ArrayList or an empty ArrayList if no matches found.
Any of the parameters, last, first, or middle may be
null. If a parameter is null then that part of the
name is ignored for matching purposes. For example, passing
in (Smith, null, null) would return all books by any author with the
last name “Smith” regardless of first or middle name; passing in (null,
null, null) would return all books by any author. Hint: you
will probably want to put this matching logic in the Name class so you
can use it for other methods which do similar matching.
- ArrayList<Book>
findBooksByTitle(String title) – Returns an ArrayList of all books
matching the specified title, otherwise an empty ArrayList.
- ArrayList<BookOnTape>
findBookOnTapeByReader(String last, String first, String middle) –
Similar to findBooksByAuthor() above but returns an ArrayList of
BookOnTape objects that match the specified Reader. Ask me if
you need further clarification.
- ArrayList<CD>
findCDsByArtist(String last, String first, String middle) – Similar to
findBooksByAuthor() above but returns an ArrayList of CD objects
matching the specified Artist. Ask me if you need further
clarification.
- ArrayList<CD>
findCDsByTitle(String title) – Similar to findBooksByTitle() above but
returns an ArrayList of CD objects matching the specified
title. Ask me if you need further clarification.
- Implement an abstract
class called Product.
- With a
private static int to use as a source of unique IDs when you are
constructing new products. The first product should added to
the inventory should have a value of 100000 and each subsequent product
should get an ID one larger.
- With the
following private instance fields:
- An int to
contain the unique ID of a product.
- An int to
contain the number of units in stock.
- A String to
contain a description of the product.
- A double
representing the wholesale price of the product.
- A double
representing the retail price of the product.
- With the
following two constructors:
- Product() –
Using the private static in defined above, this constructor should
assign a unique value to the private instance variable representing the
product ID and initialize the other instance fields as necessary and
appropriate.
- Product(int
productID) – Assign the productID passed in to the private instance
variable representing the product ID and initialize the other instance
fields as necessary and appropriate.
- Notice the
lack of specific direction regarding initialization of most of the
instance variables – the choices you make in your constructors will
impact how you implement rest of the class methods, especially the
equals method.
- The following
public accessor and mutator methods – ask if you need clarification
about what these methods should do:
- int
getProductID()
- int
getQuantity()
- void
setQuantity(int quantity)
- String
getDescription()
- void
setDescription(String description)
- double
getWholesalePrice()
- void
setWholesalePrice(double)
- double
getRetailPrice()
- void
setRetailPrice(double)
- Override the
equals(Object) method of Object. This should be a well-formed
equals method as described in class and in your text. DO
NOT include the unique productID or quantity
instance fields as part of the equality test. We want the
equals() method to consider logically identical products as equal
regardless of their unique product ID or quantity on hand.
All other instance variables of this class should be compared as part
of the equality test for this class.
- Implement an abstract
class called AbstractBook that extends
Product.
- With the
following public int constants:
- FICTION
(Constant used by the getType/setType methods - value of constant to be
determined by you)
- NONFICTION
(Constant used by the getType/setType methods - value of constant to be
determined by you)
- With the
following private instance fields:
- A String to
represent the title of the book.
- A String to
represent the publisher of the book.
- A Name
(class described below) reference to represent the author of the book.
- An int to
represent the type, FICTION or NONFICTION, of the book.
Initial value should be FICTION.
- With the
following constructors:
- AbstractBook()
– See matching super-class constructor description for behavior.
- AbstractBook(int
productID) – See matching super-class constructor description for
behavior.
- Notice the
lack of specific direction regarding initialization of most of the
instance variables – the choices you make in your constructors will
impact how you implement rest of the class methods, especially the
equals method.
- Remember that
the super-class needs to be initialized without
using any of the mutator methods.
- With the
following public accessor and mutator methods – ask if you need
clarification about what these methods should do:
- String
getTitle()
- void
setTitle(String)
- String
getPublisher()
- void
setPublisher(String)
- Name
getAuthor()
- void
setAuthor(Name)
- int getType()
- void
setType(int)
- Override the
equals(Object) method of the Product class. This should be a
well-formed equals method as described in class and in your
text. Make sure you include all instance fields of this class
and consider its super-class without
using explicit accessor methods.
- Implement a
class called Book that extends
AbstractBook.
- With the
following public int constants:
- HARD_COVER
(Constant used by getBinding/setBinding – value of constant to be
determined by you)
- PAPERBACK
(Constant used by getBinding/setBinding – value of constant to be
determined by you)
- With the
following private instance fields:
- An int to
represent the number of pages in the book.
- An int to
represent the binding type, HARD_COVER or PAPERBACK. Initial
value should be HARD_COVER.
- With the
following constructors:
- Book() – See
matching super-class constructor description for behavior.
- Book(int
productID) – See matching super-class constructor description for
behavior.
- Notice the
lack of specific direction regarding initialization of most of the
instance variables – the choices you make in your constructors will
impact how you implement rest of the class methods, especially the
equals method.
- Remember that
the super-class needs to be initialized without
using any of the mutator methods.
- With the
following public accessor and mutator methods – ask if you need
clarification about what these methods should do:
- int getPages()
- void
setPages(int)
- int
getBinding()
- void
setBinding(int)
- Override the
equals(Object) method of AbstractBook. This should be a
well-formed equals method as described in class and in your
text. Make sure you include all instance fields of this class
and consider its super-class without
using explicit accessor methods.
- Implement a
class called BookOnTape that extends
AbstractBook.
- With the
following public static int constants:
- TAPE
(Constance used by
getFormat/setFormat – value of constant to be determined by you)
- CD
(Constance used by
getFormat/setFormat – value of constant to be determined by you)
- DVD
(Constance used by
getFormat/setFormat – value of constant to be determined by you)
- With the
following private instance fields:
- A Name
(class described below) reference to represent the reader of the book.
- An int to
represent the length of the BookOnTape in minutes.
- An int to
represent the format, TAPE, CD, or DVD. Initial value should
be TAPE.
- With the
following constructors:
- BookOnTape()
– See matching super-class constructor description for behavior.
- BookOnTape(int
productID) – See matching super-class constructor description for
behavior.
- Notice the
lack of specific direction regarding initialization of most of the
instance variables – the choices you make in your constructors will
impact how you implement rest of the class methods, especially the
equals method.
- Remember that
the super-class needs to be initialized without
using any of the mutator methods.
- With the
following public accessor and mutator methods – ask if you need
clarification about what these methods should do:
- Name
getReader()
- void
setReader(Name)
- int
getLength()
- void
setLength(int)
- int
getFormat()
- void
setFormat(int)
- Override the
equals(Object) method of AbstractBook. This should be a
well-formed equals method as described in class and in your
text. Make sure you include all instance fields of this class
and consider its super-class without
using explicit accessor methods.
- Implement a
class called CD that extends
Product.
- With the
following private instance fields:
- A String to
represent the title of the CD
- A Name
(class described below) to represent the name of the artist
- With the
following constructors:
- CD() – See
matching super-class constructor description for behavior.
- CD(int
productID) – See matching super-class constructor description for
behavior.
- Notice the
lack of specific direction regarding initialization of most of the
instance variables – the choices you make in your constructors will
impact how you implement rest of the class methods, especially the
equals method.
- Remember that
the super-class needs to be initialized without
using any of the mutator methods.
- With the
following public accessor and mutator methods – ask if you need
clarification about what these methods should do:
- String
getTitle()
- void
setTitle()
- Name
getArtist()
- void
setArtist(Name)
- Override the
equals(Object) method of Product. This should be a
well-formed equals method as described in class and in your
text. Make sure you include all instance fields of this class
and consider its super-class without
using explicit accessor methods.
- Implement a
class called Name.
- With the
following private instance fields:
- A String to
represent the first name of a person.
- A String to
represent the middle name of a person.
- A String to
represent the last name of a person.
- With the
following constructors:
- Name() –
Initializes all instance variables as necessary.
- Name(String last,
String first, String middle)
– Initializes all instance variables to the values passed in.
- Notice the
lack of specific direction regarding initialization of most of the
instance variables – the choices you make in your constructors will
impact how you implement rest of the class methods, especially the
equals method.
- With the
following public accessor methods (ask if you need clarification about
what these methods should do):
- String
getFirst()
- String
getMiddle()
- String
getLast()
- With the
following public “utility” method:
- match(String last,
String first, String middle) –
This method should determine if the last, first, and middle names
passed in match this Name object’s instance fields with
this special
caveat: If a null is
passed in for one (or more) of the names it should be ignored for
matching purposes. For example, if the object’s last name is
“Smith”, its first name is “Bob”, and it middle name is “” (empty
string) and someone calls match( “Smith”, null, null) then match
returns true. If someone called match(“Smith”, “Jane”, “”) on
the same object the method would return false. Another
example, calling match(null, null, null) would return true for any Name
object.
- Override the
equals(Object) method of Object. This should be a well-formed
equals method as described in class and in your text. Make
sure you include all instance fields of this class when determining
equality.
Suggestions
- Remember to use the tests and given documentation to understand the conditions in which your implementation should work.
- Follow
the test-driven development style by first reading the given JUnit test
for the method you want to implement, then implement that method's
functionality and watch the test pass. If the test is not given,
then write the test for how the method should work, see that it fails
(since you have not written the code yet), then write the code to pass
the test.
- Keep
track of your hours worked as you go, so you don’t have to guess when you
hand in your assignment (see handin section below for information on
time.txt).
Testing
With the Provided Tests
- Your code must be 100% correct
to recieve credit. Correctness will be determined by running the acceptance
test P4TestDriver.java to be published Monday 2/4.
- In addition to the acceptance
test, sections 7 and 9 will be graded on the quality of JUnit tests they
create for this program, section 3 will not.
- Use the JUnit tests while
developing in a test-driven approach to ensure your code's correctness
before the acceptance test is released. Run them by opening the
AllTests.java file and executing it.
- Ask
your instructor for assistance if you are not able to run these tests on
your own.
Handing
in Your Source Electronically…
- Create a plain text file called
time.txt to log the amount of time spent on the assignment. The file will contain only three lines
with the following information on each line: name, project number, hours
spent.
Example time.txt file:
Sally Student
Program 4
7.5 hours
- Move the
necessary file(s) to your vogon account using your favorite FTP client
program.
- Log on to vogon using your favorite Shell client program.
- Change
directory (cd-command) to the directory containing the file(s) to hand
in. Be sure you code compiles and runs correctly on vogon before
turning it in!
- Use the
following handin
command being sure to:
- Replace the x with the
correct maximum score you can earn based on the due date, i.e., replace
y with 100 if you are handing in by Monday’s deadline, 90 for Tuesday,
80 for Wednesday, or 70 for Thursday, for example Program4-100,
Program4-90, et cetera.
12:01pm vogon ~$ handin graderkm
Program4-y
Inventory.java Product.java
AbstractBook.java Book.java BookOnTape.java CD.java Name.java InventoryTest.java BookOnTapeTest.java CDTest.java time.txt