The SOLID Programming Principles OOP(s)!

We can think of these as a general guide. There are many more, here are the ones I come up often, they are five and go by the acronym of S.O.L.I.D.

The good thing about SOLID is that helps you decouple/breaking apart your code. Giving our modules independence of each other and make our code more maintainable, scalable, reusable and testable.

A quick disclaimer: In the world of OOP sometimes is easy to fall into an obscure path of developing an hierarchy of deeply nested classes that makes it even worse (looking at you J**a & M$ C# devs) . So take the next points as advice or ideas, suggestion, not a mandatory thing.

1) Single Responsibility (SRP)

We should aim to break our code down into modules of one responsibility each.

For example we have a big class that's performing unrelated jobs:

We can now identify what the class does, test it more cleanly, and we can reuse parts of it anywhere without having to worry about irrelevant methods!

2) Open / Closed Principle (OCP)

We design our modules to add new functionality in the future without having to actually makes change to them. Instead we should extend a module to add to it, wrapping it, or something else.

In practice, we could create an object/structure lets say named 'Controller', and than if we want to create new derived classes like 'AdminController'.

This goes both ways, we should add new functionality by creating new derived classes and leave the original class implementation as it is, and also create the base class in a way it can be extended and used.

3) Liskov Substitution (LSP)

We should only extend modules when we are absolutely sure they are the still the same type as heart.

In this simple example, do you see what's wrong? I will be weird for Bicycle to extend Vehicle because doesn't really have an engine or a fuel type. (and yeah, assuming is a classic bicycle )

In short: Extend things that makes sense to extend, don't do it just to grab some kind of functionality/behavior from it. If hat's the case, it should extend something else that fits it's design... or become it's own type.

4) Interface Segregation (ISP)

Our modules shouldn't need to know about functionality they don't use, we should split our module into smaller abstractions, like interfaces... and then we can compose it to form the exact set of functionality the module requires.

This becomes very useful in Testing, as it allows us to mock only the functionality that each module needs.

Rather than creating large interfaces, create multiple smaller interfaces to allow clients to focus on the methods that are relevant to them.

In the example or HP Printer module extends IPrinter, but our printer can't scan at all; so that breaks this principle. Instead we should have something like:

No class should be forced to implement any interface method(s) that it does not use.

5) Dependency Inversion (DIP)

Its says that our modules instead of talking directly to other modules inside your code, we should always communicate abstractly, usually via the interfaces we define.

This isolates our modules completely from one another, meaning we can swap parts as we need to. I'd say this is more important on lower level modules.

Because they communicate with interfaces now, our modules don't need to know what type of 'implementation' they are getting. Only that they take certain inputs and return a valid output.

Looking at the example, we can see that instead of communicating directly to GooglePay from our modules, we go thru our interfaces and that allow us to fully decouple our higher level code, from the lower level code (The specific implementations of it), we could add new or swap to different ones without touching the rest of our application.

About
Related Posts
  • Fancy words in Tech Episode III: Design patterns

    This is a immense topic, but on this post I will try to summarize the core concepts and explain the most common design patterns in software (or at least those I've personally run into during my career); like a "cheatsheet", or like a public personal note, that most likely will need to keep updating.

  • Fancy words in Tech Episode II: GraphQL

    It's been around for many years, and like other buzz-words many companies choose the tech just because "certain FANG company uses", then It must be good for my solution. Here i will try to summarize the most important key points of this technology, when and where is intended to be used and what a developer does when working on a project like this.

  • Using Makefiles to improve Docker image build experience

    Makefile is a building tool that's been around forever; and while some of us may remember it from building our first couple projects (and may hate those times and the struggle); But I believe it's an awesome tool that by just adding a single file to our project It can speed / easy up our daily work flow on: how we build, run locally, etc our 'Dockerized' projects

Comments
The comments are closed on this section.
Hire me!

I'm currently open for new projects or join pretty much any project i may fit in, let me know!

Read about what I do, or contact me for details.