Sunday, April 06, 2014

Object Oriented Programming Principles - SOLID


1. Single Responsibility Principlethere should not be more than one reason for a class to change, or a class should always handle single functionality. If you put more than one functionality in one Class in Java  it introduce coupling between two functionality and even if you change one functionality there is chance you broke coupled functionality,  which require another round of testing to avoid any surprise on production environment.

2. Open/Closed principle Classes, methods or functions should be Open for extension (new functionality) and Closed for modification.  The idea was that once completed, the implementation of a class could only be modified to correct errors; new or changed features would require that a different class be created. That class could reuse coding from the original class through inheritance. The derived subclass might or might not have the same interface as the original class.
Meyer's definition advocates implementation inheritance. Implementation can be reused through inheritance but interface specifications need not be. The existing implementation is closed to modifications, and new implementations need not implement the existing interface.

3. Liskov substitution principle - “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.” 

4. Interface segregation principle - “many client-specific interfaces are better than one general-purpose interface.

5. Dependency inversion principle - one should “Depend upon Abstractions. Do not depend upon concretions.

The principle states:
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.

This is facilitated by the separation of high-level components and low-level components into separate packages/libraries, where interfaces defining the behavior/services required by the high-level component are owned by, and exist within the high-level component's package. The implementation of the high-level component's interface by the low level component requires that the low-level component package depend upon the high-level component for compilation, thus inverting the conventional dependency relationship. 
Another way to think of it is,
Low level components = server side
High level components = client side

Both server and client sides depend on the same interface (contract). The server side needs to implement the interface required by client side. The interface source files are required for server side compilation as well. This brings in the dependency of server side on client side (which is inverse of the dependency of client on server).

 Various patterns such as Plugin, Service Locator, or Dependency Injection are then employed to facilitate the run-time provisioning of the chosen low-level component implementation to the high-level component.

No comments: