61

I'm trying to get into OOP lately, and I'm having trouble with SOLID principles and design patterns. I see why people use them, and I really want to use them too, but I can't wrap my head around developing my classes to the specifications. I would really appreciate anything that would help my understanding of such.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
will
  • 1,491
  • 1
  • 19
  • 28
  • 3
    I think good understanding of this comes only with work experience, important is experience in a team with GOOD developers – sll Dec 03 '12 at 21:37
  • I think you should be a little more specific, maybe to a particular principle that's causing you trouble. – Carlos Gavidia-Calderon Dec 03 '12 at 21:58
  • Try learning from anti-patterns. Try writing a small app that purposely violates the advice of SOLID and an app that follows the advice and see what is less painful to write. – MatthewMartin Dec 04 '12 at 01:23
  • voted against reopening because this is way too broad. I recommend reading some of Robert Martin's articles, they have much better examples than the Head-First book. – Nathan Hughes Sep 20 '15 at 02:43
  • Maybe the SOLID diagram will help. https://swarch.blog/the-five-principles-for-solid-software-design/ – Mike Mar 28 '18 at 07:08
  • Can check bellow link https://davesquared.net/2009/01/introduction-to-solid-principles-of-oo.html – Md. Sajedul Karim Sep 10 '18 at 11:15
  • You may check this blog - https://bootsity.com/php/understanding-the-solid-principles-of-software-engineering – prady00 Apr 26 '19 at 07:02
  • This blog might help you and others to understand the concepts SOLID Principles in C# https://codewhisperer.in/index.php/2023/07/01/solid-principles-in-c-the-blueprint-for-clean-and-scalable-code/ – Vicky Jul 02 '23 at 06:13

1 Answers1

131

I've taken a class in college that spent two weeks around design patters, and read the Gang of Four book to no avail. Understanding what each pattern served for and how to use them to fit my problems was very hard for me, a developer that didn't have much experience in OO programming.

The book that really made it click for me was Head First Design Patterns. It starts by showing a problem, different approaches the developers considered, and then how they ended up using a design pattern in order to fix it. It uses a very simple language and keeps the book very engaging.

Design patterns end up being a way to describe a solution, but you don't have to adapt your classes to the solution. Think of them more as a guide that suggest a good solution to a wide array of problems.

Let's talk about SOLID:

  1. Single responsibility. A class should have only one responsibility. That means that for example, a Person class should only worry about the domain problem regarding the person itself, and not for example, its persistence in the database. For that, you may want to use a PersonDAO for example. A Person class may want to keep its responsibilities the shortest it can. If a class is using too many external dependencies (that is, other classes), that's a symptom that the class is having too many responsibilities. This problem often comes when developers try to model the real world using objects and take it too far. Loosely coupled applications often are not very easy to navigate and do not exactly model how the real world works.
  2. Open Closed. Classes should be extendible, but not modifiable. That means that adding a new field to a class is fine, but changing existing things are not. Other components on the program may depend on said field.
  3. Liskov substitution. A class that expects an object of type animal should work if a subclass dog and a subclass cat are passed. That means that Animal should NOT have a method called bark for example, since subclasses of type cat won't be able to bark. Classes that use the Animal class, also shouldn't depend on methods that belong to a class Dog. Don't do things like "If this animal is a dog, then (casts animal to dog) bark. If animal is a cat then (casts animal to cat) meow".
  4. Interface segregation principle. Keep your interfaces the smallest you can. A teacher that also is a student should implement both the IStudent and ITeacher interfaces, instead of a single big interface called IStudentAndTeacher.
  5. Dependency inversion principle. Objects should not instantiate their dependencies, but they should be passed to them. For example, a Car that has an Engine object inside should not do engine = new DieselEngine(), but rather said engine should be passed to it on the constructor. This way the car class will not be coupled to the DieselEngine class.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Uri
  • 2,207
  • 2
  • 21
  • 21
  • 7
    +1 for the book recommendation. The GoF design patterns book is difficult to understand. The Head First book is an absolute must-read to get to the next level of programming. – Bob Horn Dec 04 '12 at 01:14
  • 26
    **1)** It should have one reason to change. That's different than one responsibility. **2)** No. you should not modify classes at all. Extension is the same thing as inheritance. **3)** It can have a `Bark` method if it also has a `CanBark` method. ;) **4** Correct, but pretty lame example ;) **5** That's dependency injection. Dependency inversion says that you should depend on abstractions and that higher level moduleshould depend on lower level modules and not vice versa. – jgauffin Dec 04 '12 at 08:23
  • Started reading that book. It's a significant help. Thanks. – will Dec 20 '12 at 21:49
  • 4
    Best example of Liskov I've ever read. – lolololol ol Nov 04 '17 at 05:30
  • @SudipBhandari: The question is closed, but I've written a few posts about solid in my blog: http://blog.gauffin.org/tag/solid/ – jgauffin May 16 '18 at 18:13
  • 1
    @jgauffin - link doesn't work – Michu93 Mar 10 '21 at 18:59
  • @jgauffin "It can have a Bark method if it also has a CanBark method." >> adding canBark method itself will break LSV isn't it? – Govinda Sakhare Aug 02 '22 at 07:59
  • you got me wrong. The base class should have CanBark and Bark. In that case, all implementors do not have to implement Bark (just return false from CanBark). It's just a way to design classes to adhere to LSP while still having optional features. – jgauffin Aug 11 '22 at 10:02
  • @jgauffin did you mean **should not** depend – Adham Nov 24 '22 at 21:18
  • in which sentence? – jgauffin Nov 25 '22 at 08:50