From BertrandMeyer's ObjectOrientedSoftwareConstruction, there was the statement (quoting from memory):
Classes, interfaces, functions, etc. all become large and bloated when they're trying to do too many things.
When a function has too many responsibilities, it becomes buried deep in SpecialFormatting, which has a CodeSmell.
To avoid bloat and confusion, and ensure that code is truly simple (not just quick to hack out) we have to practice CodeNormalization, which seems to be a variation on OnceAndOnlyOnce and also DoTheSimplestThingThatCouldPossiblyWork.
This is part of ResponsibilityDrivenDesign.
On the XpMailingList, BrianButton gave us this rule of thumb:
I've been looking for this quote in ObjectOrientedSoftwareConstruction and haven't been able to find it. Can someone pinpoint the quote? Thanks. -- JimWeirich
From CodeNormalization: "In OO, a class's statement of responsibility (a 25-word or less statement) is the key to the class. It shouldn't have many 'and's and almost no 'or's (see OneResponsibilityRule). The idea for 25 words or less comes from PeterCoad in his patterns and strategies book." -- JohnStoshMuczynski
Does the ExtremeProgramming simplicity goal "MinimumNumberOfClassesAndMethods" go against this rule? Click to find out.
I think a useful corollary to this rule is the CompleteResponsibilityRule: once a class or method takes on a responsibility, it should take full and sole responsibility. -- BobKerns
What about Toolkits? Do they smell, or is this an exception?
A SwissArmyKnife may have many tools but it does not make the knife into a screwdriver - it has a separate screwdriver.
Criticism
This is often unrealistic for real-world apps. Non-trivial things tend naturally to have interweaving concerns [CrossCuttingConcerns]. Forced isolation will often create problems because it's not modeling that natural interweaving well. There's some existing topics on this somewhere around here. I'll link them as I find them. LimitsOfHierarchies hints at some of the issues. ResponsibilityDrivenDesignConflictsWithYagni is another. -t
It's only unrealistic if you're falling into the naive business domain modelling trap that suggests software objects should mirror real-world objects. Objects and object-oriented programming are most appropriately and effectively used to create computational engines that manipulate business facts, not make business simulators that (badly) emulate business processes. In the former case -- or in domains where there is no inclination to model the "real world" (e.g., developing operating systems, system utilities, productivity tools, word processors, etc.) -- the OneResponsibilityRule makes sense and is highly analogous to normalisation of relational databases.
{But OneResponsibilityRule is still a good guideline to follow. OptimizeLater. OneResponsibilityRule may result in duplicate code (violating OnceAndOnlyOnce) for distinct responsibilities, but avoids coupling of unrelated responsibilities, thus making the system less rigid under requirements change and modularity.}
I'm not sure I agree as a general rule. Some separation between nouns and verbs supplies flexibility and sharing. In practice there's often many-to-many relationship. If most were one-to-one, then it may be worth it. The "natural" ties between them are often just too weak. Perhaps one can argue that its a UsefulLie, a way to DivideAndConquer our "work units" for better mental focus-unit and staff management, but in my assessment, there are better alternative partitioning techniques. -t
*boggle* You've never written object-oriented programs to meet real requirements, have you?
{Perhaps, TopMind, you should explain the situation you are imagining. In practice, 'nouns' are things like 'connection', 'queue', 'stack', 'functor object', 'input stream', 'output stream', 'unum factory', etc.. These nouns are distinguished by interface and contracts on behavior - by responsibility. You can learn much about the 'nouns' used "in practice" by researching WikiWiki and SoftwareDesignPatterns. It is true that there are relationships between objects... e.g. one might create a message stream atop an octet stream, which is a 'uses' relationship. The OneResponsibilityRule favors constructing objects that perform delegation, such that the message stream is ignorant of what happens after it flushes the octet stream. (i.e. "You give me a tube. I break these messages into bits and put the bits in that tube. What happens after that is not my responsibility.") If there are many<->many relationships, then those relationships tend to be encapsulated by behavior and responsibility of dedicated objects... e.g. using 'signals' in EventDrivenProgramming is primarily a pattern on many<->many relationships, and is a common SoftwareDesignPattern for ObjectOrientedProgramming.}
Oh boy, not the "narrow table" issue again. (I will agree that if we had better tools to manage such, I may be more prone to accept them. But so far with existing tools and conventions, "overly" narrow tables suck rotting eggs.) -t
Contributors: TimOttinger
Related: SingleResponsibilityPrinciple (MergeMe?),StreamOfConsciousness