Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Over time I could understand two parts of SOLID – the “S” and “O”.

“O” – I learned Open Closed Principle with the help of Inheritance and Strategy Pattern.

“S” – I learned Single Responsibility principle while learning ORM (the persistence logic is taken away from domain objects).

In a similar way, what are the best regions/tasks to learn other parts of SOLID (the “L”, “I” and “D”)?

References

  1. msdn - Dangers of Violating SOLID Principles in C#
  2. channel9 - Applying S.O.L.I.D. Principles in .NET/C#
  3. OOPS Principles (SOLID Principles)
share|improve this question
20  
take note that all these ideas are good ideas, and together they are very good. but if you apply them dogmatically they will cause more fail than success. –  Jarrod Roberson Jul 6 '12 at 15:16
3  
OR-Mappers are good for separation of concerns, not single responsibility principle. See this post programmers.stackexchange.com/questions/155628/… for a discussion of the differences. –  Doc Brown Jul 6 '12 at 19:48
    
@Lijo, please look at the following reference meta.stackexchange.com/q/5234/187724 –  Yusubov Jul 12 '12 at 21:30
    
Real world examples blog.gauffin.org/2012/05/… –  Lijo Nov 2 '12 at 9:17
1  
@JarrodRoberson Yep, that's why they are carefully referred to as guidelines. Also don't forget the rest of the principles: adamjamesnaylor.com/2012/11/12/… (11 in total) –  Adam Naylor Nov 12 '12 at 15:27

3 Answers 3

up vote 28 down vote accepted

I was in your shoes couple months ago till I found a very helpful article.

Each principle is nicely explained with real-world situations that each software developer may face in their projects. I am cutting short here and pointing to the reference - S.O.L.I.D. Software Development, One Step at a Time.

As pointed in comments, there is another very good pdf reading - Pablo's SOLID Software Development.

In addition, there are some good books that describe SOLID principles in more details - Good Book on SOLID Software Development.

Edit and comments of a short summary for each principle:

  • “S” – Single Responsibility Principle is driven by the needs of the business to allow change. “A single reason to change” helps you understand which logically separate concepts should be grouped together by considering the business concept and context, instead of the technical concept alone. In another words, i learned that each class should have a single responsibility. The responsibility is to just accomplish the assigned task

  • “O” – I learned Open Closed Principle and started to "prefer composition over inheritance" and as such, preferring classes that have no virtual methods and are possibly sealed, but depend on abstractions for their extension.

  • “L” – I learned Liskov Substitution Principle with help of Repository pattern for managing data access.

  • “I” – I learned about Interface Segregation Principle by learning that clients shouldn't be forced to implement interfaces they don't use (like in Membership Provider in ASP.NET 2.0). So interface should not have “a lot of responsibilities”
  • “D” – I learned about Dependency Inversion Principle and started to code that is easy to change. Easier to change means a lower total cost of ownership and higher maintainability.

As a useful resource from CodePlex was mentioned in comments, reference is included to SOLID by example

share|improve this answer
8  
Can you summarize the most useful parts of the article here? No need to copy it verbatim, but just some key points would be great in case the link ever goes dead. –  Anna Lear Jul 6 '12 at 14:25
2  
I found the following collection of articles very useful: lostechies.com/wp-content/uploads/2011/03/… –  Scroog1 Jul 6 '12 at 14:48
2  
since the lostechies articles were mentioned here there is also this solidexamples.codeplex.com (based on lostechies) –  dark fader Jul 8 '12 at 5:34
2  
+1: Great compilation ...adding link to my bookmarks! –  IAbstract Jul 8 '12 at 18:49
2  
I was one of the contributors of Pablos eBook. I'm glad that people still find it useful. :) –  Sean Chambers Jul 10 '12 at 16:33

(I)nterface Segregation and (D)ependency Inversion can be learned via unit testing and mocking. If classes create their own dependencies, you can't create good unit tests. If they depend on a too-broad interface (or no interface at all), it isn't very obvious what needs to be mocked to make your unit tests.

share|improve this answer
2  
+1 this is very much true. You don't even have to adhere to the (imo) sometimes too strict 'a unit test should only test one thing' rule: if you can't come up with a decent test suite for a class in a couple of minutes, it violates I and D and probably the rest of the alfabet as well –  stijn Jul 6 '12 at 19:00

Liskov Substitution Principle basically does not let you to overuse implementation inheritance: you should never use inheritance just for code reuse (there is composition for this)! By adhering to LSP, you can be pretty sure that there actually exists a "is-a relationship" between your superclass and your subclass.

What it says is that your subclasses must implement all of the methods of the subclass in a similar way to the implementation of the methods in the subclass. You should never override a method with implementing NOP or return null when the supertype throws exception; stated in Design by Contract terms, you should respect the contract of the method from the superclass when overriding a method. A way to defend against breaking this principle is by never overriding an implemented method; instead extract an interface and implement that interface in both classes.

Interface Segregation Principle, Single Responsibility Principle and High Coehsion Principle from GRASP are somehow related; they refer to the fact that an entity should be responsible for only one thing so that there is only one reason for change so that change is done very easily.

It actually says that if a class implements an interface then it must implement and use all those interface's methods. If there are methods that ar not needed in that particular class, then the interface is not good and must be splitted into two interfaces one that has only the methods needed by the original class. It can be regarded from a POV, that relates to the previous principle by the fact that it does not let you create large interfaces so that their implementation could break LSP.

You can see Dependency Inversion in the Factory Pattern; here both the high-level component (the client) and the low-level component (individual instance to be created) depend upon the abstraction (the interface). A way to apply it in a layered architecture: you should not define an interface to a layer in the layer that is implemented but in the module that is called. For example the API to the data source layer should not be written in the data source layer but in the buisness logic layer, where it is needed to be called. In this way, the data source layer inherits/depends on the behavior defined in the buisness logic (thus the inversion) and not vice-versa (as would be in a normal way). This provides flexibility in the design, letting the business logic work without any code change, with another entirely different data source.

share|improve this answer
1  
Great explanation on Liskov. :) –  John Korsnes Mar 13 '13 at 18:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.