Single Responsibility, the Distorted Principle

birdculture1 pts0 comments

@truehenrique | Single responsibility, the distorted principle

Single responsibility, the distorted principle

Oct 27 | Henrique F. Teixeira

Software is made by humans, for humans and machines. And humans make mistakes, consequently causing the machine to fail too.

Given this context, over time, various principles and patterns of software development have been developed and established. And they all have one thing in common: to simplify so that we can work using less cognitive effort , given that our minds are limited and the problems we have to solve are often complex enough just in their concept, without a single line of code written.

This is a very important insight I had after going through several projects throughout my career; at first, it's not easy to understand despite seeming simple:

SOLID

MVC

DDD (Domain-driven design)

Clean Architecture

Clean Code

Refactoring / Code Smells

TDD

Redux

Microservices

Microfrontends

Object-Oriented Programming (Encapsulation, inheritance, polymorphism, anemic models, overloading…)

Functional Programming (Monads, functors, closures, currying, category theory, pure functions…)

Actor Model

Law of Demeter

Serverless

Web components

And beyond software:

Agile

Scrum

Kanban

Why do we learn and study all this?

The answer might seem obvious:

"We learn and study to use it in our daily lives, always, and these are the best practices."

But is that really the right answer?

There are contexts where we don't need to use any of this, and many others where we would benefit from using only some of these patterns and practices, not all. Thus, my answer today would be:

"We learn and study to know where and when to use it in our daily lives."

The thing is, this answer only comes with experience, with reality. And often at the beginning of a career and for a long time, we find ourselves using patterns just because we recently studied them and assume that's what we should do, after all, it's a pattern! It's the right thing to do!

This last sentence results in two of the biggest problems I particularly faced throughout my career, coming from legacy code (or from myself):

Overengineering : Too much engineering and too many patterns for a simple problem.

Underengineering (I just invented this term): Too little engineering and too few patterns for a complex problem.

And these problems are things that "full-stack JavaScript" courses, frameworks, or languages generally won't teach us.

Every pattern was created from a problem. If we haven't experienced that problem, we don't need the pattern. And strongly recognizing the problem is as important, if not more important, than knowing the details of a pattern. Our job as a Software Engineer is precisely to work without "over" and without "under," just with the "engineer." First, recognize the problems, then fit the patterns (and not the other way around).

Given this introduction, I would now like to talk about a "unique case" and a very curious one:

A pattern/principle where it's very common for people not to recognize the problem it actually solves, nor even how it works, but they go around "using" (and "preaching") it everywhere. This is probably the result of a giant "game of telephone" among developers (one tells another, the other listens and tells another, and none of them actually seeks to understand it deeply). Another point that may have led to this is the simplicity of its name:

Single Responsibility Principle

Unlike "Liskov Substitution Principle," "Chain of Responsibility," or "Law of Demeter," it's very easy to read "Single Responsibility Principle" and think:

"Oh! Single Responsibility Principle, this class does more than one thing! It has more than one responsibility! Let's split it into two."

It's simple. Methods, classes, and every organism within a software should have "a single responsibility," right?

It depends on what we understand as responsibility.

To illustrate, I really like to use the dictionary:

Responsibility: Obligation to answer for one's own actions or those of others. Character or state of being responsible. Duty to answer for one's own behavior.

I highlighted the last sentence because it will be simpler to use with the example below:

Imagine you are a pizza delivery person; what is your responsibility, and what behavior are you accountable for?

Imagined it?

I would say that:

Responsibility: Deliver the pizza

Behavior you are accountable for: Carefully storing the pizza in the bag so it arrives intact, starting the motorcycle, accelerating the motorcycle, riding safely while observing traffic laws, ringing the doorbell upon arrival, and being polite to the customer.

Do we have more than one responsibility? Or do we have behaviors we are accountable for given our responsibility?

Using real-world examples makes it clearer, right?

So I'm going to make the example worse; our own pizza delivery body has organs, and they also have their responsibilities:

The heart beats...

responsibility single principle patterns answer problem

Related Articles