CompSci 308
Fall 2019
Advanced Software Design and Implementation

Simulation : Design Checklist

In the short term we always underestimate how hard things are, but in the long term we underestimate how big changes are — Ray Kurzweil

Good design cannot be achieved by simply following a formula. Although people will often make lists of good design "rules", the reality is that good designers will occasionally break the rules for good and appropriate reasons. In this class, you will be asked to design code that has three basic characteristics:

  1. Communication: Is the code easy to read and understand?
  2. Modularity: Do your classes have a small, well-defined purpose?
  3. Flexibility: Does you program contain duplication of any kind?

To help you stay focused on these goals, each project will provide a checklist of concrete things you can do in your code to help move you towards good design. Even if you follow all the items on the checklist, it will not guarantee your code is well designed — just that it does not contain basic mistakes made because you did not make proper use of what you know. These items may not cover every possible instance and sometimes you might have good reason not to follow an item to accomplish the higher level goals (if you do so, you must document the reason within your code — a good reason for comments!).

Guidelines

  1. Communication
    1. Use meaningful names: give variables, methods, classes, and packages non-abbreviated, intention-revealing names
    2. No magic values: use named constants for all specific values used multiple times or in program logic
    3. Write readable code instead of comments: use comments only to explain important design decisions or purpose of code, not to restate code logic
    4. Use scope wisely: variables should be declared as close as possible to where they are used
    5. Write "concise" code: use booleans wisely, for-each loop where possible, use Java API calls instead of implementing yourself
    6. No warnings: remove all warnings from the Java compiler
  2. Modularity
    1. No public instance variables: keep implementation details of your class hidden from the public interface
    2. No static variables: there should be no reason for shared global public state
    3. Tell, don't ask: classes should be responsible for their own data and delegate to other objects instead of doing it themselves
    4. Superclasses are their own class: superclasses should not contain any instance variables or methods specific to only some subclasses

  3. Flexibility
    1. DRY: no duplicated code, either exactly (from cutting and pasting), structurally (in flow of control or decisions), or in setup ("boilerplate" code)
    2. Use Interfaces: Declared types should be as general as possible (i.e., List instead of ArrayList, Map instead of HashMap)
    3. Single Purpose: keep classes, methods, and variables short and well named by giving them only one purpose