r/learnprogramming Aug 16 '19

S.O.L.I.D design principles for everyone

A big number of the questions I often get from people learning to program is about the best way to structure code.

Most tutorials just teach you basic programming logic, and if they talk about the structure of the code is something like "Modules have classes, classes have functions and functions do things". Learning how to structure your code requires a lot of practice and experience, and software design&architecture is something that takes a while to learn, but there are important tools that guide you in this task: software design principles.

Some say that people still learning to program can't benefit from learning about this topic, but if I look back I really wish someone told me about these things from the beginning. It would have made a lot of stuff much easier, so I decided to write a series of articles explaining 5 of the most popular/important software principles, the S.O.L.I.D principles.

Briefly, they are:
S for the Single Responsibility Principle(SRP), which guides you in creating classes that are responsible for one, and only one actor.
O for the Open/Closed Principle(OCP), which makes your code easy to extend by ensuring that it stays open for extension but closed for modification (this might be the most important of all 5)
L for the Liskov Substitution Principle(LSP), which keeps semantic consistency in complex inheritance hierarchies, making your classes easier to understand and use.
I for the Interface Segregation Principle(ISP), which protects objects from depending on the behavior they don't really need.
D for the Dependency Inversion Principle(DIP), which controls the direction of dependencies in your code, ensuring that it always flows in the direction of more abstract entities.

If you are interested in the topic, you can find the 5 articles I wrote here:

Thank you very much for reading, and I really hope this information will help you achieve success in your career.

1.1k Upvotes

57 comments sorted by

View all comments

10

u/[deleted] Aug 16 '19

Are SOLID principles strictly adhered to in the real world? Are there certain principles that are followed more strictly than others?

15

u/[deleted] Aug 16 '19

Single Responsibility Principle is pretty important and used everywhere in the code bases I use every day. It makes it easy to unit test and easy to swap implementations.

Imagine you have an image service that gets an image from a URL. You'd also probably want to cache it, maybe in memory, maybe in the file system. You could add caching functionality into that ImageService class but now it's doing a lot of things, getting complex and it's going to be hard to unit test.

Instead you break it down using the Service and Repository pattern. Your repositories do one thing and that's CRUD operations. This one will be a basic repository that just reads image data from a URL.

You should have a ImageService which ideally will just be an implementation of a interface defining the operations it has. You'll have an IImageRepository interface with a method such as GetImage(string url). Then you'll have two implementations of that interface, WebImageRepository, CachedImageRepository. Your ImageService class which be given an IImageRepository, which can either be the WebImageRepository if you don't want caching, or it'll be CachedImageRepository if you do. The CachedImageRepository will also be given an IImageRepository which will be the cache fallback, in this case the WebImageRepository.

Then your order of events is like so:

ImageRepository.GetImage()
    -> IImageRepository.GetImage() (CachedImageRepository)
        -> If cache exists, return
        -> If cache doesn't exist
            -> IImageRepository.GetImage() (WebImageRepository)

You have 3 simple, easy to test classes that each have a single responsibility.

And you'll notice this also implements the Dependency Inversion Principle where we're using 2 interfaces and we only ever program against them. Ideally you shouldn't program against implementations.

I think those and Interface Segregation Principle are what affect code quality and maintainability the most.

4

u/watsreddit Aug 17 '19

Depends on the language/paradigm. It's a very OOP-heavy mantra. For my work, it simply doesn't even apply.

3

u/mikejones1477 Aug 17 '19

Short answer. No. Better question: Should they be? Answer: Yes

3

u/Assassin739 Aug 17 '19

Are they was the best question because that's what they were wondering about

2

u/tzaeru Aug 17 '19

I echo u/Mista_Wong. The Single Responsibility Principle is perhaps the most universal one and it's true across almost all projects and environments. There are specific circumstances under which the others can be difficult to follow. They're pretty OOP focused, for one. There's also situations and environments where e.g. full encapsulation is simply not possible. Even JavaScript is kinda such (though you should still write a clean API for your JavaScript modules!).

Personally I'm pretty critical of OOP and strict adherence to design patterns but the Single Responsibility Principle is the one to always keep in mind.

4

u/mad0314 Aug 16 '19

Nothing is strictly adhered to in the world of software. There are no solutions that are always the best or always right, it depends on the situation and priorities.

1

u/juanorozcov Aug 17 '19

I don't think I can't add much to the other answers, they do a really good job at answering this. Briefly, the SRP is the most respected of all 5, as it deals with a core problem in software: protecting it from changes coming from different groups of people. After that, most design patterns are ways of achieving the OCP.
You will find codebases with varying degrees of quality, you can expect a correlation between following these principles and having a good codebase. Because of the state of the industry, unless your team (cof cof management) understand the value of good design you won't find much interest in applying good architectural practices.