Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.programming > #6300 > unrolled thread

Thoughts on the Single Responsibility Principle.

Started byDaniel Pitts <usenet@coloraura.com>
First post2016-03-06 20:25 -0800
Last post2016-03-09 06:48 -0800
Articles 6 — 5 participants

Back to article view | Back to comp.programming


Contents

  Thoughts on the Single Responsibility Principle. Daniel Pitts <usenet@coloraura.com> - 2016-03-06 20:25 -0800
    Re: Thoughts on the Single Responsibility Principle. "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2016-03-07 09:23 +0100
    Re: Thoughts on the Single Responsibility Principle. Richard Heathfield <rjh@cpax.org.uk> - 2016-03-07 14:49 +0000
    Re: Thoughts on the Single Responsibility Principle. Julio Di Egidio <julio@diegidio.name> - 2016-03-07 08:58 -0800
    Re: Thoughts on the Single Responsibility Principle. Jos V <xjosx@xjosaphatx.co> - 2016-03-09 00:30 -0500
      Re: Thoughts on the Single Responsibility Principle. Julio Di Egidio <julio@diegidio.name> - 2016-03-09 06:48 -0800

#6300 — Thoughts on the Single Responsibility Principle.

FromDaniel Pitts <usenet@coloraura.com>
Date2016-03-06 20:25 -0800
SubjectThoughts on the Single Responsibility Principle.
Message-ID<nbivme$j6j$1@dont-email.me>
Hello,
I was recently thinking about the Single Responsibility Principle, and 
one of the thoughts I had was that it an be applied to *all* levels of 
software crafting.

I think it is relatively self-evident that methods/functions should "do 
one thing", and that classes should "encapsulate one concept".

But, I want to take the idea further.  Namespaces/packages should 
contain only things relevant to one responsibility.  And a "Project" 
should also be limited in its responsibility.

The difference is that the smaller the scope, the more specific the 
responsibility should be.

For example, a projects responsibility might be "Provide email access", 
a package in that project might be "provide SMTP support", a class in 
that package might be a "Manage SMTP Connection", and a method on that 
class might have the responsibility of "Send authentication".

I'd even say that statements (in imperative languages) should also have 
one responsibility.  This means statements such as "foo = ++bar;" are 
breaking the SRP, as the statement is responsible for incrementing bar 
*and* copying the result to foo.

Maybe what I'm saying here is so self-evident that I shouldn't have 
brought it up, or maybe what I'm saying is just plain wrong, or even 
oversimplified.  I'd like feedback.

Thanks,
Daniel.

[toc] | [next] | [standalone]


#6301

From"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Date2016-03-07 09:23 +0100
Message-ID<nbjdrj$1olk$1@gioia.aioe.org>
In reply to#6300
On 07/03/2016 05:25, Daniel Pitts wrote:

> I was recently thinking about the Single Responsibility Principle, and
> one of the thoughts I had was that it an be applied to *all* levels of
> software crafting.
>
> I think it is relatively self-evident that methods/functions should "do
> one thing", and that classes should "encapsulate one concept".

Self evident also is that this does not work for no less evident 
reasons. But otherwise appropriately formulated, Occam's razor works for 
SW design.

> I'd even say that statements (in imperative languages) should also have
> one responsibility.  This means statements such as "foo = ++bar;" are
> breaking the SRP, as the statement is responsible for incrementing bar
> *and* copying the result to foo.

Nope. That depends on the concept here. The concept can well be 
"increment and copy" indivisibly. E.g. in concurrent programming atomic 
increment+latch is an important fundamental concept.

The morale is, the "concept" is the problem space entity. Otherwise, 
when considered in isolation it is pretty much arbitrary. What is single 
responsibility in one context could be multiple in another as you move 
along abstraction levels and computational frameworks.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

[toc] | [prev] | [next] | [standalone]


#6302

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-03-07 14:49 +0000
Message-ID<nbk48m$93m$1@dont-email.me>
In reply to#6300
On 07/03/16 04:25, Daniel Pitts wrote:

<snip>

> I'd even say that statements (in imperative languages) should also have
> one responsibility.  This means statements such as "foo = ++bar;" are
> breaking the SRP, as the statement is responsible for incrementing bar
> *and* copying the result to foo.
>
> Maybe what I'm saying here is so self-evident that I shouldn't have
> brought it up, or maybe what I'm saying is just plain wrong, or even
> oversimplified.  I'd like feedback.

I think the SRP is just plain wrong. Please bear with me while I paint a 
picture. (A picture is not proof! But it can illustrate a truth, if 
we're careful.)

I hope we can all agree that putting the entire program into a single 
function is a mistake, for all but the very simplest of programs. Let's 
say that we have a million things to do, and that each thing takes one 
line. The function would be a million lines long, which is ludicrous. We 
can think of this as being a very tall, very narrow program.

Okay, so let's go the other way. Let's have a million functions instead.

We now have a very short, very wide program. And it's just as ridiculous.

But we can make a lot more sense of the program if it has, say, a 
thousand functions, each a thousand lines long. Now the program is still 
quite tall, but not unmanageably so. And it's still quite wide, but not 
unmanageably so.

That's my picture. Now for my argument. So you can stop bearing with me 
now. :-)

If we had a Single Responsibility /Strategy/, I could live with that. 
Let's try to make each function do one small job and do it well, but 
let's accept that there will be times when it makes more sense for the 
function to do a bigger job, because it makes some /other/ job simpler.

But a Single Responsibility /Principle/ brooks no argument. We cannot 
say, with Groucho Marx, "these are my principles, and if you don't like 
them... well, I have others". We must stick to our principles, right? 
And if we don't stick to them, our code will fail the review. And so we 
have /no choice/ but to go with the very short, very wide program. Every 
function will be a one-liner. Every function must take only one 
parameter. Every function must return only one value. Banish the IF! 
It's ridiculous. It leads sensible, thoughtful people to wonder whether 
we should turn

foo = ++bar;

into

foo = bar + 1; ++bar;

It will turn short functions into long functions, and then it will 
insist that those long functions be turned into two or more shorter 
functions, and we end up with a million one-line functions.

NO, sir! I will cheerfully accept that a Single Responsibility Strategy 
can help to make maintenance easier when it is applied as /one/ of a 
number of tools for writing better software. But I cannot accept it as a 
principle.

These, ladies and gentlemen, are my strategies, and if /I/ don't want to 
go where they lead, I have /other/ strategies.

It isn't a great one-liner, is it? But that's kind of the point. I'd 
rather have a thousand great one-thousand-liners than a million great 
one-liners.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#6303

FromJulio Di Egidio <julio@diegidio.name>
Date2016-03-07 08:58 -0800
Message-ID<cc09834e-a34a-4fa4-aaf3-b510f7d9a161@googlegroups.com>
In reply to#6300
On Monday, March 7, 2016 at 4:25:46 AM UTC, Daniel Pitts wrote:
> Hello,
> I was recently thinking about the Single Responsibility Principle, and 
> one of the thoughts I had was that it an be applied to *all* levels of 
> software crafting.

The SRP is some variant of what in software design is called Cohesion: in short, the one fundamental engineering principle of design is Modularity, which is achieved in software by maximising Cohesion and minimising Coupling.  That said, two remarks:

Design principles apply at the design level, not at all levels: the maximum level of granularity remains a functional unit (a unit of "responsibility").  But, for example, at the level of coding we rather have Readability and altogether another story.

But those principles, at any levels, are only half of the story, software artefacts are *intrinsically* complex, not only in their structure, and not even only in their behaviour, but in the very construction process: it was called Development for a reason, it is a dynamic process that rather requires that we always keep a balance between Optimality and *Redundancy*!  (E.g., as a rule of thumb, I do not extract code into a separate function until I have at least 3 places using it...)

HTH,

Julio

[toc] | [prev] | [next] | [standalone]


#6309

FromJos V <xjosx@xjosaphatx.co>
Date2016-03-09 00:30 -0500
Message-ID<Y8qdncUrr5lmKULLnZ2dnUU7-b_NnZ2d@giganews.com>
In reply to#6300
On 03/06/2016 11:25 PM, Daniel Pitts wrote:
> Hello,
> I was recently thinking about the Single Responsibility Principle, and
> one of the thoughts I had was that it an be applied to *all* levels of
> software crafting.
> 
> I think it is relatively self-evident that methods/functions should "do
> one thing", and that classes should "encapsulate one concept".
> 
> But, I want to take the idea further.  Namespaces/packages should
> contain only things relevant to one responsibility.  And a "Project"
> should also be limited in its responsibility.
> 
> The difference is that the smaller the scope, the more specific the
> responsibility should be.
> 
> For example, a projects responsibility might be "Provide email access",
> a package in that project might be "provide SMTP support", a class in
> that package might be a "Manage SMTP Connection", and a method on that
> class might have the responsibility of "Send authentication".
> 
> I'd even say that statements (in imperative languages) should also have
> one responsibility.  This means statements such as "foo = ++bar;" are
> breaking the SRP, as the statement is responsible for incrementing bar
> *and* copying the result to foo.
> 
> Maybe what I'm saying here is so self-evident that I shouldn't have
> brought it up, or maybe what I'm saying is just plain wrong, or even
> oversimplified.  I'd like feedback.
> 
> Thanks,
> Daniel.
> 
> 

You've mostly got it, but you have to be pragmatic. Especially when you
start trying to define what constitutes a "project" and what constitutes
a line of code.  Your prime directive should be managing complexity;
modularity and the SRP go a long way towards that.

But when you start trying to break up a single project into multiple
projects you'll start to find ways in which the divisions aren't so neat
and where you start trying to invent complicated ways to make it work.
Depending on the goals of the end product, this might make sense, but
you have to be pragmatic.  Facebook is a single "project" with a single
responsiblity, "social networking", but that's so broad as to be almost
meaningless. The web interface encompasses Chat, blogging, alerts,
entire applications, ad serving, etc., and a lot of those pieces have
nothing to do with "social networking".

You also start running into problems if you try to break lines of code
up by "single responsibility".

    incrementedBar = bar + 1; // Exhibit A
    foo = incrementedBar;
    bar = incrementedBar;

But wait! You've fixed the problem with ++bar, but now you're stuck with
"Exhibit A" that has the same problem!

You just need to be pragmatic.  SRP is a good rule-of-thumb way of
looking at code, but your focus should be on making sure that the code
doesn't get too complex for humans to understand.

-- 
Jos

[toc] | [prev] | [next] | [standalone]


#6311

FromJulio Di Egidio <julio@diegidio.name>
Date2016-03-09 06:48 -0800
Message-ID<af8ba34b-4f20-4fe8-a690-3fa2f909806f@googlegroups.com>
In reply to#6309
On Wednesday, March 9, 2016 at 5:30:39 AM UTC, Jos V wrote:
> On 03/06/2016 11:25 PM, Daniel Pitts wrote:
> > Hello,
> > I was recently thinking about the Single Responsibility Principle, and
> > one of the thoughts I had was that it an be applied to *all* levels of
> > software crafting.
> > 
> > I think it is relatively self-evident that methods/functions should "do
> > one thing", and that classes should "encapsulate one concept".
> > 
> > But, I want to take the idea further.  Namespaces/packages should
> > contain only things relevant to one responsibility.  And a "Project"
> > should also be limited in its responsibility.
> > 
> > The difference is that the smaller the scope, the more specific the
> > responsibility should be.
> > 
> > For example, a projects responsibility might be "Provide email access",
> > a package in that project might be "provide SMTP support", a class in
> > that package might be a "Manage SMTP Connection", and a method on that
> > class might have the responsibility of "Send authentication".
> > 
> > I'd even say that statements (in imperative languages) should also have
> > one responsibility.  This means statements such as "foo = ++bar;" are
> > breaking the SRP, as the statement is responsible for incrementing bar
> > *and* copying the result to foo.
> > 
> > Maybe what I'm saying here is so self-evident that I shouldn't have
> > brought it up, or maybe what I'm saying is just plain wrong, or even
> > oversimplified.  I'd like feedback.
> 
> You've mostly got it, but you have to be pragmatic. Especially when you
> start trying to define what constitutes a "project" and what constitutes
> a line of code.  Your prime directive should be managing complexity;
> modularity and the SRP go a long way towards that.
> 
> But when you start trying to break up a single project into multiple
> projects you'll start to find ways in which the divisions aren't so neat
> and where you start trying to invent complicated ways to make it work.
> Depending on the goals of the end product, this might make sense, but
> you have to be pragmatic.  Facebook is a single "project" with a single
> responsiblity, "social networking", but that's so broad as to be almost
> meaningless. The web interface encompasses Chat, blogging, alerts,
> entire applications, ad serving, etc., and a lot of those pieces have
> nothing to do with "social networking".
> 
> You also start running into problems if you try to break lines of code
> up by "single responsibility".
> 
>     incrementedBar = bar + 1; // Exhibit A
>     foo = incrementedBar;
>     bar = incrementedBar;
> 
> But wait! You've fixed the problem with ++bar, but now you're stuck with
> "Exhibit A" that has the same problem!
> 
> You just need to be pragmatic.  SRP is a good rule-of-thumb way of
> looking at code, but your focus should be on making sure that the code
> doesn't get too complex for humans to understand.

Agreed overall, just you need a lot of study, too: e.g. principles are not just rules of thumb (which are rather called best practices, and so on: there is a *discipline* there)!  You need *both*, study and practice, and a commitment to do things properly or it is useless anyway: software engineering is the most complex engineering that there is, with just trial and error in 10 years you'd still be trying to get your head around for loops...

Julio

[toc] | [prev] | [standalone]


Back to top | Article view | comp.programming


csiph-web