http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
A CLASS SHOULD HAVE ONLY ONE REASON TO CHANGE.
If a class assumes more than one responsibility, then there will be more than one reason for it to change. If a class has more than one responsibility, then the responsibilities become coupled. Changes to one responsibility may impair or inhibit the class’ ability to meet the others. This kind of coupling leads to fragile designs that break in unexpected ways when changed.
What is a Responsibility? In the context of the Single Responsibility Principle (SRP) we define a responsibility to be “a reason for change.” If you can think of more than one motive for changing a class, then that class has more than one responsibility.
YOU SHOULD BE ABLE TO EXTEND A CLASSES BEHAVIOR, WITHOUT MODIFYING IT.
Modules that conform to the open-closed principle have two primary attributes.
- They are “Open For Extension”. This means that the behavior of the module can be extended. That we can make the module behave in new and different ways as the requirements of the application change, or to meet the needs of new applications.
- They are “Closed for Modification”. The source code of such a module is inviolate. No one is allowed to make source code changes to it.
DERIVED CLASSES MUST BE SUBSTITUTABLE FOR THEIR BASE CLASSES.
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.
MAKE FINE GRAINED INTERFACES THAT ARE CLIENT SPECIFIC.
When clients are forced to depend upon interfaces that they don’t use, then those clients are subject to changes to those interfaces. This results in an inadvertent coupling between all the clients. Said another way, when a client depends upon a class that contains interfaces that the client does not use, but that other clients do use, then that client will be affected by the changes that those other clients force upon the class. We would like to avoid such couplings where possible, and so we want to separate the interfaces where possible.
DEPEND ON ABSTRACTIONS, NOT ON CONCRETIONS.
-
A. HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS.
-
B. ABSTRACTIONS SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTIONS.