Warehouse Inheritance

Introduction

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.

Item Class Requirements

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.

LocationItem Requirements

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.

FixedLocationItem Requirements

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.

ThresholdLocationItem Requirements

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.

PreferredLocationItem Requirements

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.

GroupItem Requirements

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".

NearGroupItem Requirements

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".

AvoidGroupItem Requirements

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".

Submitting

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.

Item Classes (50%)

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.

JUnit Tests (50%)

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.