JMU CS345 - Software Engineering
Help Policies Solutions Study-Aids Syllabus Tools
Homework: Design Patterns


1 Purpose

The primary purpose of this assignment is to help you review (and demonstrate that you have acquired) the knowledge and skills required to use design patterns.

2 Overview

As you know from an earlier assignment, SagaciousMedia is a (fictitious) company that develops educational hardware, software, and content for both the formal and informal education markets. SagaciousMedia's products are designed to excite and educate students, to inspire and assist teachers/instructors, and to help administrators. They are in the process of developing a product called Transcriptz.

They have decided that their earlier design was both too complicated and not flexible enough. Hence, for this assignment you must implement their new and improved design. In particular, you must use the composite pattern to: (a) make it possible to have arbitrarily complicated grading schemes, and (b) eliminate the need for the History and Cohort classes.

3 Starting Point

This assignment builds on H1 and H4. You may start with either your solution to those assignment or mine. However, there is no guarantee that my code is correct; it does not contain any intentional defects, but may contain unintentional defects. You are responsible for any and all defects in your submission.

4 Documents

SagaciousMedua has created several new documents for this release.

Note that these documents provide details where they are needed (e.g., where they have changed from the earlier designs) and omit them where they are not (e.g., where they haven't changed from the earlier designs).

5 Testing

Some of the tasks that you must complete involve unit testing. You must use JUnit for this purpose. Your JUnit test suite must cover all statements and all branches (as measured by EclEmma) in all of the classes/enums you submit, including the classes/enums from earlier assignments (whether you actually wrote them or I did). You should neither write tests for, nor submit, the main classes. Your tests must be in a package named testing and each test class must include the word "Test" in its name.

6 Questions to Think About Before Starting

You should answer these questions after you read the assignment and before you start writing any code. You do not need to submit the answers.

6.1 Questions about the Design

The design of this version is significantly different from the design of the previous version.
  1. LabeledDouble is now an interface, not a class. Why?
  2. Some of the functionality that was in the LabeledDouble class has been moved into the AbstractLabeledDouble class and some of it has been moved into the LeafLabeledDouble class. Why?
  3. The new CompositeLabeledDouble class uses a Filter and/or Calculator to calculate the numerical value for the collection. What design pattern is being used in this regard (i.e., in the calculation of the numerical value)? What are the benefits? (Hint: The answer is not the composite pattern. The composite pattern describes the relationship between the LabeledDouble interface, LeafLabeledDouble class, and CompositeLabeledDouble class.)

6.2 Questions about the Implementation

There are almost always different ways to implement specifications. As when solving any problem, you should consider the different alternatives, evaluate them, and choose the best one. Some things to think about in this regard include the following.
  1. You should almost never catch and re-throw the same exception though sometimes you may need to catch one and throw another. Why?
  2. You shouldn't use exception handling when an if statement can be used. For example, you should almost never catch a NullPointerException you should, instead, use an if statement to see if the object is null. Why?
  3. Declarations should be as flexible and generic as possible. Instantiations must be specific. Why?

7 A Recommended Process

As before, the tasks that were identified by the team at SagaciousMedia are organized by story. Hence, though they are numbered so that they can be referred to in documents and conversations, the numbers should not, in any way, influence the order in which you complete them.

In this case, it is particularly important that you give some thought to the order in which you make changes to the existing code, since it can be done fairly efficiently or very inefficiently. In other words, the refactoring tool in Eclipse can be very helpful if used thoughtfully or it can create an enormous amount of unnecessary work if used sloppily.

I would suggest you sequence your activities as follows. However, you should think about how this process will work for you given the way you implemented your tests.

  1. Read and understand all of the documents.
  2. Answer the "Questions to Think About".
  3. Create a new project for this version.
  4. Copy the SizeException and Numerics classes from the previous version.
  5. Copy the LabeledDouble class from the previous version.
  6. Copy all of the tests from the previous version.
  7. Refactor the LabeledDouble class (using the tool in Eclipse), renaming it to LeafLabeledDouble.
  8. Implement the LabeledDouble interface.
  9. Implement the AbstractLabeledDouble class.
  10. Modify the LeafLabeledDouble class so that it now specializes the AbstractLabeledDouble class.
  11. Modify the tests as necessary. Specifically, when you refactored the LabeledDouble class and renamed it LeafLabeledDouble, Eclipse made the change everywhere. In some cases (e.g., in List objects), you should change it back to LabeledDouble (e.g., from List<LeafLabeledDouble> to List<LabeledDouble>).
  12. Perform regression testing on the LeafLabeledDouble class (using the tests that you originally wrote for the LabeledDouble class and debug it if necessary.
  13. Copy the other classes and interfaces from the previous version of the math package.
  14. Perform regression testing on all of these classes and debug them if necessary.
  15. Implement the CompositeLabeledDouble class.
  16. Test and debug the CompositeLabeledDouble class.
  17. Copy the LetterGrade and JMUCourseTable classes from the previous version.
  18. Copy the InputUtilities class from the previous version.
  19. Re-write the InputUtilities class so that it uses CompositeLabeledDouble objects in place of History and Cohort objects (e.g., both readGradeHistory() and readCohort() must now return a CompositeLabeledDouble object). The readCohort() method must return a CompositeLabeledDouble object that uses a null Filter and a WeightedAverageCalculator with null weights. It must pass the Filter and Calculator that it is passed to the readGradeHistory() method for it to use.
  20. Perform regression testing on the InputUtilities class.
  21. Test and debug the complete system using TranscriptzH5 class. When running the main class it is a good idea to include the full path and file name in the command-line/run arguments, otherwise, depending on where you put the files, you will get a FileNotFoundException. (Remember to put the whole thing in quotes if it contains spaces.)

8 Submission

You must submit (using Gradescope) a .zip file that contains:
  1. "Your" implementation of all of the required interfaces/classes/enums in the appropriate package(s) and all other necessary classes (excluding the main classes).
  2. JUnit tests for all of the classes/enums you submit (in a package named testing).

You may submit your code up to 10 times with no penalty. After the 10th submission, your grade will be reduced by 5 points for each submission. Given the work you have completed so far, you should only need one submission.

9 Grading

The code portion of your submission will be graded as follows:

Note that you will not be given hints if your code does not conform to the style guide and/or does not pass your tests. You must now identify and correct these issues in your development environment.

As always, points will be deducted manually for code that is unclear, inelegant, and/or poorly documented.

Copyright 2024