Skip to content

HW2: Campus Shipping v2

Campus Shipping Logo

Learning Objectives

This homework assignment is designed to help you learn several things. First, it will help you learn about the difference between static and non-static members. Second, it will help you learn about arrays. Third, it will help you learn about loops and accumulators.

Overview

The former JMU students that opened Campus Shipping have decided to ship products other than books (e.g., shirts, computers) and this has made them realize that their original design for the calculator was bad. In particular, they realize that if they were to continue with the current design they would need to have a utility class for each product (e.g., a BookShippingCostCalculator, a ShirtShippingCostCalculator, a ComputerShippingCostCalculator, etc.), and that each of these classes would be very similar, contain duplicate code, and be very difficult to maintain. So, they have changed the design so that they can have an object for each product rather than a utility class for each product.

For example, with the old design, if Campus Shipping handled books and shirts, they would need two almost identical utility classes and would use them as follows:

  double total;
  total = BookShippingCostCalculator.cost(41) + ShirtShippingCostCalculator.cost(300);

With the new design they will need only one class and will use it as follows:

  double total;
  ShippingCostCalcultor books, shirts;
  books = new ShippingCostCalculator(36, 2.20);
  shirts = new ShippingCostCalculator(120, 0.50);
  total = books.cost(41) + shirts.cost(300);

The Classes to be Written

You must write two "normal" classs named ShippingCostCalculator and ShipmentProfile.

The ShippingCostCalculator Class

A ShippingCostCalculator object can be used to determine the shipping cost for any item that is shipped on pallets.

The UML Class Diagram

The following UML class diagram provides an overview of the attributes and methods in this class (which must be in the hw2 package, though that is not shown in the UML class diagram).

Class Diagram

Notice that there are several important differences between this "normal" class and the utility class from the previous assignment.

  • Some of the attributes are now non-static and, so, belong to individual objects in the class rather than the class itself.
  • The non-static attributes are now initialized in an explicit value constructor.
  • The methods are now non-static and, so, can make use of the non-static attributes (that have different values for each object in the class).

Detailed Design Specifications

  1. The constructor must initialize the attributes of the object.
  2. Each of the other methods must provide the same functionality that is provided by the corresponding method in BookShippingCostCalculator class, but must work for anything that can be shipped on pallets (not just books).

The ShipmentProfile Class

A ShipmentProfile encapsulates the information that is needed to calculate shipping costs for a shipment that contains multiple items.

The UML Class Diagram

The following UML class diagram provides an overview of this class (which must be in the hw2 package, though that is not shown in the UML class diagram).

Class Diagram

Detailed Design Specifications

In addition to the specifications contained in the UML class diagram, this class must conform to the following specifications.

  1. The explicit value constructor must initialize the array of ShippingCostCalculator objects based on the parameters it is passed.
    1. It must assume that the parameters are conformal arrays (i.e., that element i of the two arrays correspond to the same item).
    2. It need not check the lengths of the parameters it is passed (i.e., it may assume that the lengths are the same and non-zero).
  2. The shippingCost() method must return the total cost of the shipment given the shipment sizes of all of the items. Question to think about… How would you make the shippingCost() method return 0 when the length of the parameter is even?
    1. It must assume that the parameter it is passed is conformal with the attribute (i.e., that element i of the parameter corresponds to element i of the attribute).
    2. It need not check to ensure that the length of the array it is passed has the appropriate length (i.e., it may assume that the length of the parameter and the length of the attribute are the same).

Submission

You must submit (using Gradescope):

  1. A .zip file with the directory/folder hw2 at the top-level that includes your implementation of the ShippingCostCalculator class and your implementation of the ShipmentPofile class.

There is no limit on the number of submissions and no penalty for excessive submissions. Note that your submission will not be graded if it does not comply with the specifications. So, your submission should include a stubbed-out version of all of the classes. (This will allow you to get credit for the classes/methods that you do implement correctly.)

Grading

Your code will first be graded by Gradescope and then by the Professor. The grade you receive from Gradescope is the maximum grade that you can receive on the assignment

Gradescope Grading

Your code must compile (in Gradescope, this will be indicated in the section on "Does your code compile?") and all class names and method signatures must comply with the specifications (in Gradescope, this will be indicated in the section on "Do your class names, method signatures, etc. comply with the specifications?") for you to receive any points on this assignment. Gradescope will then grade your submission as follows:

Criterion Points Details
Conformance to the Style Guide 20 points (Partial Credit Possible)
Correctness 80 points (Partial Credit Possible)

Gradescope will provide you with hints, but may not completely identify the defects in your submission.

Manual Grading

After the due date, the Professor may manually review your code. At this time, points may be deducted for inelegant code, inappropriate variable names, bad comments, etc.

Since nobody will be looking over your shoulder, you can use any process that you would like to use. However, it is strongly recommended that you use the process described here.

Get Started

  1. Read and understand the entire assignment.
  2. Create a directory/folder for this assignment (under src) named hw2.

Copy and Rename BookShippingCostCalculator.java

  1. Outside of VSCode, copy BookShippingCostCalculator.java from the directory/folder named hw1 to the directory/folder named hw2.
  2. Within VSCode, rename BookShippingCostCalculator.java to ShippingCostCalculator.java (and allow the refactoring changes).
  3. Understand what changes were made to the source code by the previous step.

Make ShippingCostCalculator.java a "Normal" Class

  1. Delete the initialization of all of the attributes that are now non-static (and save the file).
  2. Understand why this generated several syntax errors.
  3. Remove the final modifier from all of the attributes that are now non-static (and save the file).
  4. Understand why this resolved the syntax errors.
  5. Make the appropriate attributes non-static (i.e., remove the static modifiers).
  6. Understand why this generated several style errors.
  7. Understand why this also generated several syntax errors in the methods that follow.
  8. Rename the attributes (and save the file). (Hint: Highlight the attribute identifier, right-click on the highlighted identifier, pull down to [Rename Symbol], type the new identifier, and press [Enter]. Notice that this changes the identifier everywhere in the class.)
  9. Understand why this resolved the style errors.
  10. Remove the static modifier from all of the methods (and save the file).
  11. Understand why this resolved the syntax errors.
  12. Write the explicit value constructor.

Test the ShippingCostCalculator Class

  1. Copy BookShippingTest.java from the directory/folder named hw1 to the directory/folder named hw2.
  2. Rename it to ShippingTest.java (and make any necessary changes).
  3. Modify ShippingTest.java so that it can be used to test ShippingCostCalculator.java for a shipment of books.
  4. Run the tests and debug ShippingTest.java if necessary.

Write the ShipmentProfile Class

  1. Create a file named ShipmentProfile.java.
  2. Stub-out the class.
  3. Implement the constructor.
  4. Implement the shippingCost() method.

Test the ShipmentProfile Class

  1. Create a file named ShipmentProfileTest.java.
  2. Using paper-and-pencil, create some test cases for an item named shirts.
  3. Using paper-and-pencil, create some test cases for an item named decals.
  4. Add the tests to the main() method of the ShipmentProfileTest class.
  5. Test the ShipmentProfileTest class.
  6. If necessary, debug the ShipmentProfile class.

Tip

As discussed before, classes used in testing should either start or end with Test.

Relevant Programming Patterns

In addition to those that were relevant for "Campus Shipping v1", an understanding of the following programming patterns will help you complete this assignment:

Questions to Think About

You don't have to submit your answers to these questions, but you should try to answer them because they will help you determine whether or not you understand some of the important concepts covered in this assignment.

  1. What compile-time errors are generated in the ShippingCostCalculator class if you make the attributes in it static? Why?
  2. Why would it have been impossible to include the ShipmentProfile class in v1?