Tuesday 11 December 2012

S.O.L.I.D. Principles in Object Oriented Programming

Single Responsibility Principle (SRP)

It states that every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class. There should not be more than one reason to change the class. This means class should be designed for one purpose only. This principle states that if we have 2 reasons to change for a class, we have to split the functionality in two classes. Each class will handle only one responsibility and on future if we need to make one change we are going to make it in the class which handles it. When we need to make a change in a class having more responsibilities the change might affect the other functionality of the classes.

Example- Sales Order class: This class is using for CRUD functionality of Sales Order, and then it should not have any method to MAP Sales Order attributes with Database columns, because later if there is any new column added in Database  the class need to be modified which is violating the rule of Single Responsibility Principle.


Open/Close Principle (OCP)

It states that Class should be open for extension, but close for modification. At first, this seems to be contradictory: how can you make an object behave differently without modifying it? The answer: by using abstractions, or by placing behavior (responsibility) in derivative classes. In other words, by creating base classes with override-able functions, we are able to create new classes that do the same thing differently without changing the base functionality. 


Liskov Substitution Principle (LSP) 

Basically when we designed a class, we use maintain Class hierarchies. We must make sure that the new derived classes just extend without replacing the functionality of old classes. Otherwise the new classes can produce undesired effects when they are used in existing program modules.
LSV states that if the module using any base class, then the reference to the Base class can be replaced with a Derived class without affecting the functionality of the program module. 

Example: - A typical example that violates LSP is a Square class that derives from a Rectangle class, assuming getter and setter methods exist for both width and height. The Square class always assumes that the width is equal with the height. If a Square object is used in a context where a Rectangle is expected, unexpected behavior may occur because the dimensions of a Square cannot (or rather should not) be modified independently. This problem cannot be easily fixed: if we can modify the setter methods in the Square class so that they preserve the Square invariant (i.e. keep the dimensions equal), then these methods will weaken (violate) the post conditions for the Rectangle setters, which state that dimensions can be modified independently. If Square and Rectangle had only getter methods (i.e. they were immutable objects), then no violation of LSP could occur.

Interface Segregation Principle (ISP)

It states avoid tying a client class to a big interface if only a subset of this interface is really needed. Many times you see an interface which has lots of methods. This is a bad design choice since probably a class implementing. . This can make it harder to understand the purpose of a component, but it can also cause increase coupling, where by components that make use of such a component are exposed to more of that components capabilities that are appropriate.
The Interface Segregation Principle (or ISP) aims to tackle this problem by breaking a components interface into functionally separate sub-interfaces. Although a component may still end up with the same set of public members, those members will be separated into separate interfaces such that a calling component can operate on the component by referring only to the interface that concerns the calling component. 

Dependency Inversion Principle (DIP)

In an application we have low level classes which implement basic and primary operations and high level classes which encapsulate complex logic and rely on the low level classes. A natural way of implementing such structures would be to write low level classes and once we have them to write the complex high level classes. Since the high level classes are defined in terms of others this seems the logical way to do it. But this is not a flexible design. High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.

No comments:

Post a Comment

Custome Service Class to connect wcf service

  using  System; using  System.ServiceModel; namespace Custom.Service.Client {      // Borrowed from: http://old.iserviceoriented.com/blog/p...