A short summary of object oriented design principles to increase maintainability, reusability, flexibility, less complexity
Single Responsibility Principle
Each module should take just one responsibility/functionallity and all responsibilities/functionallities should be assigned to exactly one module. As a consequence, there is only a single reason why a module needs to be adjusted: the requirements for which it is responsible, have changed. If you have to reasons to change a module, it should be splitted into 2 modules.
Separation of Concerns
Each concern should be represented by only one module. Don’t distribute the concern over more modules. (But the module certainly can use others to fulfill its responsibility)
Don’t repeat yourself
Eeach single functionality of a softwre should be implemented within the system only once.
A module should be open for extensions. To change the functionallity, the module itself should be able to be combined with additionally modules, containing only the deviations to the original functinality.
A module should be closed for modifications. No changes of the module should be necessary in order to expand it but it should offer extension points for additionally modules, changing the functionallity.
Liskov’s Substitution Principle
A new derived module has to extend the base modules without changing their behavior.
Program to interfaces
Any dependency between two modules should be explicitly stated and documented. A module should always be depended from a well defined interface of another module, independet from the implementation.
Interface Segregation Principle
Clients should not be forced to implement interfaces they don’t use. Instead of one fat interface many small interfaces are preferred based on groups of methods, each one serving one submodule.
Dependency Inversion Principle
Our design should be based on abstractions and not on spezific variants. Designing under this principle should start at the high level module: High Level Module–> Abstraction Layer –> Low Level Module
Make it testable
Reduce the complexity of a design to increase testability. If a functionallity is hard to test, maybe it should be changed by adding some abstraction, clearly define interfaces or adding extension points. So a higher testability leads to a better design.