46

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)
LCJ
  • 977
  • 2
  • 13
  • 23
  • 28
    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. –  Jul 06 '12 at 15:16
  • 4
    OR-Mappers are good for separation of concerns, not single responsibility principle. See this post http://programmers.stackexchange.com/questions/155628/what-is-the-difference-between-single-responsibility-principle-and-separation-of for a discussion of the differences. – Doc Brown Jul 06 '12 at 19:48
  • Real world examples http://blog.gauffin.org/2012/05/solid-principles-with-real-world-examples/ – LCJ Nov 02 '12 at 09:17
  • 1
    @JarrodRoberson Yep, that's why they are carefully referred to as __guidelines__. Also don't forget the rest of the principles: http://www.adamjamesnaylor.com/2012/11/12/SOLID-Principles-Of-Object-Orientated-Programming.aspx (11 in total) – Adam Naylor Nov 12 '12 at 15:27
  • 2
    @AdamNaylor 's link is now 404ing, its been moved to http://www.adamjamesnaylor.com/post/SOLID-Principles-Of-Object-Orientated-Programming – mattumotu Aug 09 '16 at 15:04

3 Answers3

57

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

enter image description here

Yusubov
  • 21,328
  • 6
  • 45
  • 71
  • 3
    I found the following collection of articles very useful: http://lostechies.com/wp-content/uploads/2011/03/pablos_solid_ebook.pdf – Scroog1 Jul 06 '12 at 14:48
  • I read that whole article and I am not sold on patterns or on SOLID. The example is too simplistic, but when it gets complex that complexity is artificial. I am yet to encounter real world SOLID OOP without better alternatives. – Job Jul 07 '12 at 03:46
  • 3
    since the lostechies articles were mentioned here there is also this http://solidexamples.codeplex.com/ (based on lostechies) – dark fader Jul 08 '12 at 05:34
  • 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
  • 1
    +1000000 if I could for your summary of the Open-Closed principle - everybody gets this wrong and thinks it's about inheritance – Alex Jul 31 '14 at 16:48
  • @SeanChambers In page 30 of the eBook, the last paragraph says "... can we extend ... ProductFilter ... No! This means it is not OPEN for extension". But in fact it *can* be extended (in the way that OCP prescribes) by creating a subclass with the additional filter methods. At least, that is what I understand OCP is about, as defined by Bertrand Meyer in his "Object-Oriented Software Construction" book (1988, 1997). Or is there some other definition of OCP? – Rogério Feb 27 '15 at 18:29
13

(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.

StriplingWarrior
  • 2,407
  • 1
  • 16
  • 21
  • 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 06 '12 at 19:00
8

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.

Random42
  • 10,370
  • 10
  • 48
  • 65