SOLID Principles of Programming

0

Category :

Robert C Martin introduced the acronym SOLID in the early 2000s to communicate five high level principles for object oriented programming. The five principles are:

Single Responsibility – an object should have only one responsibility.

Objects created in this fashion are considered more durable over the long term because they have only one reason to change. Using the single responsibility principle will cause you to have many more classes.
However, the more granular your classes become, the easier it will be to maintain and modify those classes without impacting a large portion of your code.
http://codebetter.com/karlseguin/2008/12/05/get-solid-single-responsibility-principle/

Open/Closed – an object is open for extension, but closed for modification.

This principle is implemented by utilizing the other SOLID principles in conjunction with object oriented development patterns. How do you make modifications, sometimes major modifications, without breaking your existing code? Applying the open/closed principle you would not modify the existing code; rather, through implementing software development patterns, you would add new functionality, taking advantage of the existing software, without changing the way it works internally.
That is the reason that SOLID is an acronym. Each of the principles work hand in hand and cannot stand alone. For example, the Single Responsibility pattern we reviewed yesterday provides a framework for Open/Closed. If each object has a single responsibility, it is a lot easier to lock them down (Close) while still adding new functionality at a later time (open).
If you would like to see an example of code techniques implementing Open/Closed, I found a great article in MSDN magazine by Jeremy Miller, http://msdn.microsoft.com/en-us/magazine/cc546578.aspx, from 2008 demonstrating how the SOLID principles may be implemented through different object oriented patterns.

Liskov Substitution – An object should be replaceable with instances of a subtype without altering the correctness of a program.

Liskov postures that your specific class implementations should utilize an abstract implementation of external objects. In so doing, you can change the functionality of that class by substituting a different implementation of the abstract external object with another, and the containing class need not be modified in any way. In essence, this is one technique for fulfilling the Open/Closed principle.
an object called BusinessProcess. BusinessProcess requires interaction with a data source. Rather than instantiating a specific data source the BusinessProcess class utilizes an IDataSource interface. By using an interface the BusinessProcess object works with any implementation of the IDataSource interface.
The IDataSource interface can be implemented by an XML data store. Later it may be implemented with a relational database data store without modifying the BusinessProcess class in any manner.
In this fashion, Single Responsibility, Open/Closed and Liskov Substitution work together resulting in code that may be easily extended with the least impact to existing code. Utilizing other software development patterns, new implementations of IDataSource may be created, instantiated, and inserted into the program for execution by adding only new code, and modifying configuration data for implementation.

Interface Segregation – segregated interfaces are better than on single general purpose interface.

Unlike the other principles we have covered up to this point, Single Responsibility, Open/Closed, and Liskov Substitution, the Interface Segregation Principle is less transferable to languages that are not object oriented.
If I were to summarize the principle into one sentence it would be, “it is better to have more tightly defined interfaces rather than fewer comprehensive interfaces.”.
A rule of thumb might be, if you can foresee a realistic potential for the need to separate an interface into smaller interfaces because the interface contains features that do not apply to all implementations, then it makes sense to break it out.
This is where refactoring comes into play. Perhaps your interface was too general when you started out. That doesn’t mean you can’t break the interface out into smaller more granular interfaces at a later date. It just takes more work; especially if you don’t have automated unit tests to prove your refactoring work hasn’t broken your business requirements.

Dependency Inversion = Base your code on abstractions such rather than concrete implementations.

If your class dependencies are based on abstractions (Interface or abstract class) then the classes implementing the abstractions may be replaced without impacting any and every consumer.
Dependency Injection is a good implementation of the Dependency Inversion Principle. Using Dependency Injection, a consumer passes a desired kind of implementation to a class capable of resolving the correct implementation required, returning the correct object. container i guess.
One of my favorite examples is having a web app that can save data to a web service, an XML File, or a relational database. The user says, Save to XML. The web application knows nothing about how to save XML; but it knows how to call a persistence controller that returns a class that will save the data as an XML file. The Class supporting XML is based on an interface shared by the web application. The Web site, in this instance is injecting through a controller, the information necessary to implement the correct type of Class to persist the data to XML.
Dependency Injection is one technique of implementing Dependency Inversion. They are not equivalent concepts.


my thanks to: http://www.sswug.org/nlarchive.aspx
first email newsletter received on 30/07/2012

0 comments:

Post a Comment