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, perspecTV is a (fictitious) company that designs, creates and markets products that provide a new perspective on television. Their products make television both more interactive and more informative. They are in the process of developing a suite of products called forScore for judged competitions of various kinds (e.g., sporting events like diving and gymnastics, singing contests, dance competitions).

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 competition structures, and (b) eliminate the need for the Dive and DiversList classes.

3 Starting Point

This assignment builds on H1 and H4. You may start with either your solution to those assignment or mine. Though there are no intentional defects, there is no guarantee that my code is correct; you are responsible for any and all mistakes in your submission.

4 Documents

perspecTV 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 PeopleScorer or TeamScorer classes. Your tests must be in a package named testing and each test class must include the word "Test" in its name.

6 A Recommended Process

As before, the tasks that were identified by the team at perspecTV 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. Create a new project for this version.
  3. Copy the SizeException and Missing classes from the previous version.
  4. Copy the Score class from the previous version.
  5. Copy all of the tests from the previous version.
  6. Refactor the Score class (using the tool in Eclipse), renaming it to LeafScore.
  7. Implement the Score interface.
  8. Implement the AbstractScore class.
  9. Modify the LeafScore class so that it now specializes the AbstractScore class.
  10. Modify the tests as necessary. Specifically, when you refactored the Score class and renamed it LeafScore, Eclipse made the change everywhere. In some cases (e.g., in List objects), you should change it back to Score (e.g., from List<LeafScore> to List<Score>).
  11. Perform regression testing on the LeafScore class (using the tests that you originally wrote for the Score class and debug it if necessary.
  12. Copy the other classes and interfaces from the previous version of the scoring package.
  13. Perform regression testing on all of these classes and debug them if necessary.
  14. Implement the CompositeScore class.
  15. Test and debug the CompositeScore class.
  16. Copy the DivFileReader class from the previous version.
  17. Re-write the DivFileReader so that it uses CompositeScore objects in place of Dive and DiversList objects (e.g., both readDive() and readDiversList must now return a CompositeScore object).
  18. Perform regression testing on the DivFileReader.
  19. Test and debug the complete system. A good place to start is to use the PeopleScorer application with the .div files from the previous assignment. The correct outputs for these files are: (ST_Complete_01.div, 63.4), (ST_Complete_02.div, 46.1), (ST_Missing-Score_01.div, 53.9), (three-dives_five-judges_drop-both.div, 131.1), and (four-dives_six-judges_drop-neither.div, 358.1). Of course, you should be able to calculate the correct answers for these files by hand, and you will need to be able to do so if you have to debug your code. When running PeopleScorer 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.)

7 Submission

You must submit (using Gradescope) a .zip file that contains:
  1. "Your" implementation of the required interfaces/classes/enums in the appropriate package(s) (including the DifficultyTable1mS class but not including the PeopleScorer or TeamScorer classes).
  2. JUnit tests for all of the classes/enums you submit (in a package named testing).

You may submit your code up to 15 times with no penalty. After the 15th submission, your grade will be reduced by 5 points for each submission.

8 Grading

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

As mentioned above, points will be deducted for excessive submissions. As always, points will be deducted for code that is unclear, inelegant, and/or poorly documented.

9 Questions to Think About

You need not submit answers to the following questions, but you should probably answer them before you start writing any code.

9.1 Questions about the Design

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

9.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?

Copyright 2024