Table of Contents
Principles Of Object Oriented Design
Single Responsibility Principle
* Each responsibility should be a separate class, because each responsibility is an axis of change. * A class should have one, and only one, reason to change. * If a change to the business rules causes a class to change, then a change to the database schema, GUI, report format, or any other segment of the system should not force that class to change.
Open Closed Principle
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
(http://www.objectmentor.com/resources/articles/ocp.pdf) BertrandMeyer first coined it in the first edition of ObjectOrientedSoftwareConstruction as follows: A class should be open for extension, but closed for modification. In other words, (in an ideal world...) you should never need to change existing code or classes: All new functionality can be added by adding new subclasses or methods, or by reusing existing code through delegation. This prevents you from introducing new bugs in existing code. If you never change it, you can't break it. It also prevents you from fixing existing bugs in existing code, if taken to the extreme.
Liskov Substitution Principle
Barbara Liskov wrote LSP in 1988:
What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.“ - BarbaraLiskov, Data Abstraction and Hierarchy, SIGPLAN Notices, 23,5 (May, 1988).
Interface Segregation Principle
The dependency of one class to another one should depend on the smallest possible interface. (http://www.objectmentor.com/publications/isp.pdf)
Dependency Inversion Principle
- High level modules should not depend upon low level modules. Both should depend upon abstractions.
- Abstractions should not depend upon details. Details should depend upon abstractions. (http://www.objectmentor.com/resources/articles/dip.pdf)
Forces
We wish to avoid designs which are:
- Rigid (Hard to change due to dependencies. Especially since dependencies are transitive.)
- Fragile (Changes cause unexpected bugs.)
- Immobile (Difficult to reuse due to implicit dependence on current application code.)
Inversion
“Structured” methods of the 1970's tended towards a “top-down decomposition”, which encouraged high-level modules to depend on modules written at a lower level of abstraction. (More modern procedural approaches depend more on databases and less on functional decomposition at the large-scale level. Thus, they are often “flatter” now.) This principle stems from the realization that we must reverse the direction of these dependencies to avoid rigidity, fragility and immobility. [edited from Robert's original to reflect modern procedural philosophy]