CompSci 308
Fall 2018
Software Design and Implementation

SLogo : Design Checklist

The only way to make the deadline — the only way to go fast — is to keep the code as clean as possible at all times. — Robert Martin on LeBlanc's Law: "Later equals Never."

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 or CheckStyle

     

  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. Superclass's are their own class: superclass's should not contain any instance variables or methods specific to only some subclasses
    5. Active classes: classes should not have a lot of get/set methods and, in general, should minimize their use
      When necessary:
      • get methods should give away the minimal information possible
      • set methods should validate data received
    6. Delegate work: create several classes that work together distributing intelligence, rather than one "smart" class and a few "dumb" helpers

  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 Array List, Map instead of Hash-map)
    3. Single purpose: keep classes, methods, and variables short and well named by giving them only one purpose
    4. Behavior driven design: give each class a purpose by focusing on the behavior (or services) it provides first, its state later
    5. Polymorphism: use subclassing to avoid "case-based code logic" (i.e., conditional chains or case statements on "type" information)
    6. Reduce direct dependence: refer to other classes through interfaces or intermediaries rather than directly when possible