Design Principles:
#1: Whenever you design anything, always do so from the user’s (consumer’s) viewpoint. If you are designing a framework, write examples of its intended usage; this will highlight any deficiencies.
#2: Encapsulate what varies. It should be possible to alter or extend the parts that vary without affecting everything else
#3: Program to an interface, rather than an implementation (i.e. exploit polymorphism). Use a factory.
#4: Favor composition over inheritance. Do not overuse inheritance; a blend of the two often works best.
#5: Don’t Repeat Yourself (DRY principle). Every fact must have a single, unambiguous, authoritative representation within a system.
#6: Aim for loosely-coupled designs between objects that interact. Low coupling and high cohesion lead to designs that are more resiliant to change.
#7: Classes should be open for extension, but closed to modification. Able to extend existing functionality without breaking existing code.
#8: Depend on abstractions, rather than concrete classes. Use a factory.
#9: Principle of least knowledge: talk only to your immediate friends. How? Only call methods on:
- The object itself
- Objects passed in as parameters to a method
- Any object instantiated by a method
- Any composite objects (Has-a)
#10: Low level components should never call into a high-level component directly.
#11: A class should have only a single reason to change (high cohesion)
#12: Raise Exceptions only in exceptional circumstances. Do not use exceptions for normal program flow.
(these are largely due to the excellent book ‘Head First Design Patterns’ by Freeman & Freeman, O’Reilly)