TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

The Single Responsibility Principle

69 pointsby marcbarbosaabout 11 years ago

7 comments

telabout 11 years ago
This is nice and drives home something particularly important to me. In Parnas&#x27; quote he suggests <i>modularizing</i> such that &quot;things that change together stay together&quot;. I think this is highly sensible. Another way of saying it is that your <i>API</i>s should be fixed.<p>But often this gets conflated in OO because objects are the hearth of modularization (via encapsulation) along with <i>state</i> and <i>interaction</i> and any number of other things.<p>---<p>As a comparison point, you might examine ML modules. They look a bit like this<p><pre><code> module counter(X) count : X -&gt; Int incr : X -&gt; X </code></pre> and they specify nothing more than the fact that some unknown type X satisfies the interface `(count, incr)`. We can then create a concrete implementation of such a counter<p><pre><code> incCounter : counter incCounter = structure(Int) count n = n incr n = n + 1 </code></pre> The incCounter internally uses `Int` to represent `X`, but externally it&#x27;s completely impossible to tell. This means that modules define exactly two things: encapsulation and interface.<p>---<p>So why does this fall down in OO? Because objects lend themselves to being thought of as entities which move through time and space in a stateful fashion. This means you&#x27;re also likely to encapsulate differences of entity without regard for how they might change together or apart.<p>Returning to Parnas&#x27; quote: it&#x27;s a bad idea to decompose into modules based on a flowchart. Flowcharts allow you to emphasize the entities of your system, but they are not demonstrating the boundaries of change.<p>So you can probably get better OO design by being clear when you&#x27;re using objects as entities (and thus perhaps you do not need encapsulation at all!) and when you&#x27;re using them as modules. Once this distinction is made it can be clear when objects will derive from flowcharts and when objects will derive from selections of choices made by people.
stiffabout 11 years ago
While he might understand what he is talking about, based on a corpus of experience, people who learn about this &quot;principle&quot; as they learn to program do not typically understand it and tend to draw only the wrong conclusions from it. What makes for coupling, and how to avoid it, you simply learn with a lot of practice, and there are not many clearcut guidelines you can formulate, it all varies depending on the problem. At best you can read SICP and see how they decouple everything by doing lots of data-driving and dynamic dispatch and things of this sort.<p>This is too vague to be a &quot;principle&quot;, and only causes confusion. It is about as precise, and as useful, as the &quot;write good code&quot; principle.
评论 #7717398 未加载
评论 #7717670 未加载
sunirabout 11 years ago
I personally find it easier to think of it as Conway&#x27;s Law:<p>&quot;organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations&quot; - M. Conway<p>More on <a href="http://c2.com/cgi/wiki?ConwaysLaw" rel="nofollow">http:&#x2F;&#x2F;c2.com&#x2F;cgi&#x2F;wiki?ConwaysLaw</a> and <a href="http://en.wikipedia.org/wiki/Conway&#x27;s_law" rel="nofollow">http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Conway&#x27;s_law</a><p>However, I also hate this mental model of software engineering because I have often found it easier to refactor the organization. Maybe because I&#x27;m a prima donna and only like working at startups.<p>I think it&#x27;s better to require each portion of code has a narrow interface so you can reason in your mind easily about what that code segment does and should do into the future. A function or a class must promise what it should deliver given some inputs and not violate that expectation. If you ever had to reason about code using invariants, you&#x27;ll grok this.<p>More on <a href="http://c2.com/cgi/wiki?NarrowTheInterface" rel="nofollow">http:&#x2F;&#x2F;c2.com&#x2F;cgi&#x2F;wiki?NarrowTheInterface</a>
Arnorabout 11 years ago
My team and I have been working on a problem over the last week or so that screams modularity problems. Each time we think we have it solved, someone says &quot;Wait, there&#x27;s this report only 2 of us have ever heard about that doesn&#x27;t work because X, Y, Z.&quot; The discussion has lasted a couple weeks and is starting to push deployment times back.<p>Essentially, we have a distributed set of `devices` which interact with `customers`. Each customer has a `session` with the device. During the session, the `customer` may make various types of `payments` (coin or credit card) for various types of `fees`. Additionally, the customer may receive one or more `tickets`. The data model is getting pretty big with:<p>* Devices<p>* Sessions<p>* Line Items<p>* Allocations<p>* Payments<p>* Adjustments<p>* Violations<p>* Fees<p>For accounting purposes, we need to be able to map our payments to the fees and violations they are paying for. Customers might make a single payment to cover multiple violations and those violations may be across multiple sessions.<p>The number of times I&#x27;ve heard &quot;this new solution fixes X but breaks π&quot; is frustrating, but I don&#x27;t see how this could be separated out. Perhaps others have insights that would simplify all of this, but it seems to me that the essential fact of our system is that the payment&#x2F;line item&#x2F;allocation system is responsible for many tasks&#x2F;reports. I read articles like this and pine for:<p>A) A project where true modularity is achievable.<p>B) The skills to make my current project truly modular.
评论 #7719430 未加载
gone35about 11 years ago
(Warning: bikeshedding&#x2F;off-topic angry rant ahead. Please ignore.)<p>&quot;The Single Responsibility Principle (SRP) states that each software module should have one and only one reason to change. This sounds good, and seems to align with Parnas&#x27; formulation. <i>However it begs the question</i>: What defines a reason to change?&quot; (emphasis added)<p>Ok I realize that languages evolve and all; and I see how the nearly universal appeal of using the phrase &quot;begging the question&quot; in this way will ensure it will soon make its way into the dictionary; but I think people should at least know the original meaning of the phrase [1] and that, in some pedantic or predominantly academic circles today, it is considered as incorrect usage. That is all.<p>[1] <a href="http://begthequestion.info/" rel="nofollow">http:&#x2F;&#x2F;begthequestion.info&#x2F;</a>
评论 #7718996 未加载
slantedviewabout 11 years ago
The most important principle in software design. Follow SRP and so many other things just fall into place.
josephschmoeabout 11 years ago
Prior to reading this article, I always took the &quot;single responsibility principle&quot; literally, but largely do this in practice whenever possible.<p>Thank you.