SitRite3K has been a blockbuster hit for EduCorp. The CEO is determined to build on this success by branching out into other sectors. The general problem of finding an optimal arrangement of items has applications beyond students and seating charts. The goal for the next phase of development is to generalize the existing code base to handle a wide range of scenarios that involve positioning items in a grid.
One application being targeted is warehouse organization. Businesses have a need to position items on warehouse shelves to minimize the time that employees spend finding items and restocking.
This assignment will only involve the first stage of the code
reorganization. Instead of a single Student
class, the
new application will include a hierarchy of
different Item
types, each of which involves different
positioning requirements. The specification for these new classes has
been provided for you. It will be your responsibility to complete the
implementation of the new classes and to develop comprehensive unit
tests.
Item
Class Hierarchy The following UML diagram illustrates the required collection of classes. You are free to add additional private or protected helper methods, but otherwise your code must exactly match the specification below.
The Item
class serves as the base of the class hierarchy.
The constructor must throw an
IllegalArgumentException
if it is passed a negative row
or column value.
Each of the non-abstract methods should provide the obvious functionality.
The LocationItem
class serves as an abstract base class
for any Item
class that must store a target location.
See the two subclasses below for specific examples.
The constructor must throw an
IllegalArgumentException
if any of the integer arguments
are negative.
The two accessor methods must provide the obvious functionality.
The FixedLocationItem
class is used to represent objects that must be
located in a specific location in the grid. In a warehouse scenario,
this might include safety equipment that is legally required to be
located at specific points along a shelving unit.
The constructor must throw an
IllegalArgumentException
if any of the integer arguments
are negative.
The getUnhappiness
method must return 0 if the object is
at the target location and Double.POSITIVE_INIFINITY
otherwise.
The ThresholdLocationItem
class is used to represent
objects that must be located in a specific area of the grid, but not
necessarily at a specific single location.
The constructor must throw an
IllegalArgumentException
if any of the numerical arguments
are negative.
The getUnhappiness
method must return 0 if the distances
from the item to the target location is less than the threshold
distance, and Double.POSITIVE_INIFINITY
otherwise.
The PreferredItem
class is used to represent items that
have a specific preferred location in the grid. For example, if a
particular item needs to be accessed frequently, it may be desirable
to locate the item as near as possible to the warehouse entrance.
The constructor must throw an IllegalArgumentException
if any of the integer arguments are negative.
The getUnhappiness
method must return the Euclidean
distance from the item's actual location to its target location.
The GroupItem
class serves as an abstract base class for
any Item
class that must store references to a collection
of other items. See the two subclasses below for specific examples.
The constructor must throw an
IllegalArgumentException
if it is passed a negative row
or column value.
The addItem
method must add the provided item to the list of "friends".
The totalDistance
method is a protected helper method
that must return the total Euclidean distance from this item to all of
the item's "friends".
The NearGroupItem
class represents an item that should be
positioned as close as possible to some collection of other items.
(Note that this is very similar to the Student
class from
the previous projects.) In the warehouse context, this could be used
in situations where certain items are frequently purchased together.
For example, it makes sense to store umbrellas near galoshes.
The constructor must throw an
IllegalArgumentException
if it is passed a negative row
or column value.
The getUnhappiness
method must return the total Euclidean
distance from this item to all of the item's "friends".
The AvoidGroupItem
class represents an item that should
be positioned as far as possible from some collection of other items.
For example, in the warehouse context, this might be useful for
preventing flammable items from being stored near each other.
The getUnhappiness
method must return the additive
inverse (negation) of the total Euclidean distance from this item to
all of the item's "friends".
Before the deadline you must submit completed implementations of all eight Item classes above, as well as JUnit test classes for each of the five non-abstract classes. The grade for the assignment will be divided evenly between the completed Item classes and the JUnit test classes. Your final grade will be reduced by one point for each submission beyond five.
As in the previous programming assignments, code that fails any of the Web-CAT submission tests will receive at most 50% of the possible credit for this portion of this assignment. A usual, passing all submission tests does not guarantee full credit. Your submission will be evaluated on the basis of code-quality and style.
It will not be possible to receive any credit for your JUnit tests unless your Item classes pass all of the instructor-provided unit and style tests.
Your JUnit tests will be graded on the basis of code-coverage and test quality. Any submission that does not reach 100% code coverage will receive at most 50% of the possible score for this section of the assignment.
You can evaluate your test coverage before submission by uploading your code to the Web-CAT assignment named "CoverageTesting". This assignment exists purely to make it easier for you to evaluate your unit tests. Uploading your code to this assignment does not count as a submission for this project.
Your JUnit test classes must have Javadocs for the class headers, but you are not required to provide Javadoc comments for each method.
Note that your JUnit tests will inevitably include some code repetition. Each of your concrete classes inherits methods from abstract base classes. Those methods must be tested in the concrete classes because we cannot instantiate the abstract classes for testing.