Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The Single Responsibility Principle is the single most misunderstood design principle. Primarily due to its misleading name, I suspect.

A common misunderstanding is that a function or class should "only do one thing". This lead to futile discussions about what "one thing" really constitute, and tend to lead to "ravioli code" with innumerable tiny functions and objects, which is really hard to read and understand.

But the principle is about business requirement which might change independently. Don't put the tax rate calculation and the color scheme into the same class, since they might change independently, due to events outside the control of the developers. But otherwise, cohesion is just as important as decoupling. If two things are logically coupled, they should be tightly coupled in the code, otherwise you introduce accidental complexity.



The purpose of a principle is to be understood, and help us write better software with that understanding. The fact that SPR is so widely misunderstood, then, is a failure of SRP as a useful concept, not a failure of people misusing the term.

Ideally, you take a term or phrase like "single responsibility principle" and use it to discuss a particular design, interface, or implementation. If you can't do that, you have to find a different way to discuss your code.

It's like "clean code". Most people will agree that code should be "clean", but not come to any sort of agreement about what makes code "clean," or whether some specific code is "clean." The way to dig yourself out is to ban the word "clean" and ask people to explain things using different terms.

You've used one of my favorite phrases to describe code... "hard to read and understand". It is, of course, subjective. Alice may think it is easy to read and understand, Bob may think it is hard. However, it's easy enough to agree, in most cases, that everyone on the team should be able to understand the code. Therefore if I find the code hard to read and understand, that's a valid criticism of the code, even though it's a subjective criticism.

I can say, "This code is hard to understand because there's a bunch of color scheme information mixed in with the tax rate calculations." Or I can say, "This code is hard to understand because there are too many small functions." Honestly, just throw SRP in the garbage.


Hum, no. The purpose of a principle is that if you follow it you will very likely get a good result.

Being easy to understand is nowhere on it. Why is it that everything must be dumbed down? If thousands of people can't get the principle, but it gets good results to the people that understand it, it is a good principle, and those thousands of people either study a bit or decide to live with their worsened condition.

If you take the GP's single paragraph that explains the principle and tries to use it to discuss a particular design, you will see that it's perfectly possible. The fact that people can't do the same if they read a paragraph less and stop at the name is not very relevant.


> Hum, no. The purpose of a principle is that if you follow it you will very likely get a good result.

If you can't communicate the principle, then it's not a principle any more. It's just personal judgement. It's "tacit knowledge".

https://en.wikipedia.org/wiki/Tacit_knowledge

Principles are the opposite of tacit knowledge, they are explicit knowledge.

> Being easy to understand is nowhere on it.

I don't understand what this sentence means. I don't know how to parse "on" in this context and it's unclear what "it" is.

> Why is it that everything must be dumbed down?

Are you saying that "easy to understand" means "dumbed down"? If that's what you're saying, I don't agree with that.

> If you take the GP's single paragraph that explains the principle and tries to use it to discuss a particular design, you will see that it's perfectly possible. The fact that people can't do the same if they read a paragraph less and stop at the name is not very relevant.

The paragraph was vague.

The problem is that the SRP does not help you communicate problems with code. It does not help you understand problems with code. It is too vague.

Following SRP does not help you write good code, IMO.


I agree!

I recently read this article about how everybody misunderstands the SRP and uses it wrong: http://www.softwareonthebrain.com/2022/01/the-misunderstood-...

Notably it was retweeted by the author of the SRP himself: https://twitter.com/unclebobmartin/status/148522452187556249...

Now neither of them went this far with it: but if we have a programming principle that nobody understands or uses right, is it really all that useful? Maybe it at least shouldn't be the first one in SOLID?


Communicating the principle is different from understanding code which follows the principle, or does not.


Just to be clear. The thread is about an academic paper about the thing, from the 70's. And you are calling it tacit knowledge?


programming advice feels like reading management books: people with experience try to put into paper their gut feeling, after years of empirical experience... and the end result is, at best, not very scientific. At worst, is outright misleading for beginners (as they lack experience to judge when said advice is applicable)


This is why everyone learning to program should start with a language like an early BASIC with limited structured programming capabilities, no real use of subroutines (goto all the things), only global scope for variables, and no modules. Suffer a bit, then you'll appreciate things like SRP and structured programming a lot more.


> This lead to futile discussions about what "one thing" really constitute, and tend to lead to "ravioli code" with innumerable tiny functions and objects, which is really hard to read and understand.

Right I dont understand this either. Instead of one file with a few hundred lines of code lots of people prefer 20 classes/files. Drives me nuts.


On an "abstract/fuzzy" level I would say that a class with several hundreds lines of code means you are missing some terms in your domain language dictionary. For example, you might be doing a lot of inline operations on strings that represent PhoneNumber, but instead you could extract that logic into a PhoneNumber class. Even if it is only used within the scope of the larger class. Once you apply this a couple of times you will have few classes each with no more than 200 lines of code (in a language like C#).

The critical thing here is: these classes reflect terms from the domain model that can be easily intuitively understood, not some made-up abstractions adding to incidental complexity, like -Manager, -Util, -Provider, -Context, -Wrapper, and so on.

Conversely, you can imagine that you wrote a sentence, took some words from it, assumed these words don't exist, and replaced them with their dictionary definitions. Repeat a couple of times and you have your one big class. Extracting classes to capture domain language terms is like reversing this obfuscation/serialization process.

Cool article on the topic: https://www.yegor256.com/2014/11/20/seven-virtues-of-good-ob...


One of our clients is a company that franchises out their operations for different countries. I wish I could have a simple PhoneNumber class. Or simple anything class.

But realistically what happens is, e.g., each franchisee wants us to treat phone number differently than eachother. USA wants no country code. Europe does. Japan wants strict number validation. Taiwan doesn't care. And so on.

At the end of the day it all gets stored as a simple string in the database, and there's software other companies have written that can set it to whatever the hell they want so we have to handle that anyways.

Really all I need is a simple string and a validation function.


What you are saying might be a manifestation of the "bounded context" pattern/problem:

https://martinfowler.com/bliki/BoundedContext.html

It is a huge topic. Hard for me to discuss this further without knowing the specifics. But intuitively, if it was as simple as "Really all I need is a simple string and a validation function." then you wouldn't need a class with several hundred lines of code.

Or you could have UsaPhoneNumber, JapanesePhoneNumber, etc.

And instead of doing:

IsValidUsaPhoneNumber(str);

you could do:

var usaPhoneNumber = new UsaPhoneNumber(str);

and now you have the validness captured as a type:

https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va...


Splitting a larger function or class into smaller components is not in itself an improvement. Therefore I really dislike quantitative rules like "no more than 200 lines". Simple is better than complex, but splitting an otherwise cohesive module into multiple modules does not make the code simpler, it just increases the accidental complexity.

This is why SRP and this paper are important: They give qualitative guidelines for how to partition systems, not cuter-productive quantitative guidelines.




Consider applying for YC's Winter 2027 batch! Applications are open till November 2.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: