Corey Haines is well known for championing the intensive software practice events known as coderetreat. He shares his experiences from these sessions of the practice of simply designing software in the book Understanding the 4 Rules of Simple Design.
The four rules, originated by Kent Beck in the late 90s, are expressed concisely by Corey as follows:
Corey has observed patterns that have emerged from solutions to Conway’s Game of Life during many coderetreat sessions and he relates these back to the four rules.
Examples include the strategy of reification to eliminate knowledge duplication and noticing how the resultant classes act as behavior attractors. There are many more nuggets in Corey’s book so, rather than listing them here, I encourage you to read the book.
Naturally, Corey is not the only software luminary, other than Kent Beck, to have written about the four rules of simple design. Indeed, Corey refers to two fascinating articles by Joe Rainsberger that have influenced his thinking.
I like the way Joe expands upon these rules in a practical sense and distills them to their essence. As Joe concludes, good simple design practice boils down to this:
Remove duplication and improve names in small cycles.
That sounds like good advice to me.
“That’s wrong!”, interjected a member of the audience.
I was taken aback. I had suggested the following definition of the Single Responsibility Principle.
“A class should do the smallest possible thing; that is, it should have a single responsibility.”
At the time, all I could respond with was: “well, that’s one definition”. In fact, this quote was taken verbatim from Practical Objected-Oriented Design in Ruby by Sandi Metz. The purpose of my talk was to use Sandi’s excellent book to generate discussion about better OO design in Rails applications. Fortunately for me, those present at the Sydney Ruby meetup (or “rorosyd” as it is affectionately known) responded well and all ended well.
However, the experience left me pondering.
Kevlin is an Englishman who delights in the proper use of the English language. Very early in his talk he questioned the use of the word principle in relation to SOLID design. Kevlin suggested that the word pattern was more accurate. As he illustrated his point by referring to the Oxford English dictionary, it was hard to mount an argument against his criticism.
Focussing on the so-called Single Responsibility Principle, Kevlin started with the Wikipedia entry. After all, it appears first in a Google search and how could it possibly be wrong? Interestingly, the entry is both potentially misleading and illuminating. It defines SRP thus:
“Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.”
This is not so different to Sandi’s definition. However, the same Wikipedia entry also notes that Robert C. Martin introduced the term, going on to say that:
“Martin described it as being based on the principle of cohesion, as described by Tom DeMarco in his book Structured Analysis and Systems Specification.”
Here is where an exploration of the language behind the description of SRP gets interesting. Kevlin referred to Glenn Vanderburg’s article on cohesion. Glenn relates that he has had most success in explaining the term cohesion in terms of it’s etymology. In short, cohesive things belong together as opposed to those that need an adhesive to glue them together.
Bearing this in mind, let’s read what Robert C. Martin says in 97 Things Every Programmer Should Know:
“One of the most foundational principles of good design is:
Gather together those things that change for the same reason, and separate those things that change for different reasons.
This principle is often known as the single responsibility principle, or SRP. In short, it says that a subsystem, module, class, or even function, should not have more than one reason to change."
In other words, responsibility is equated to having only one reason to change. As someone else present at my rorosyd talk said in response to the first interjection, “it depends what you mean by responsibility”. Reflecting on the language used, however, leaves me thinking that the term “single responsibility” is not as helpful as the word “cohesion” when discussing good software design.
The whole of Kevlin’s talk was both thought-provoking and entertaining. He concluded by suggesting five alternatives for the SOLID principles that all begin with the letter C. In the place of SRP as the first “pattern” was Cohesion by Usage.
Kevlin’s talk has caused me to reflect on the importance of language in the context of software design.
What have I learned?
It also occurs to me that we need to guard against the increasing tendency in this day and age to only read short chunks of text. TL;DR is no excuse for those striving to be better developers.
In closing, if you’ve read this far, I’ll leave you with a recommendation. If you ever get the chance to see and hear Kevlin Henney talk about software, grab it with both hands.
One thing that the Rails community prides itself on is that test-driven development (TDD) is widely employed. But is this sufficient to produce good quality code that stands the test of changing requirements over a long period of time?
In my recent roundup of Ruby resources, Sandi Metz is one author I recommended. In her excellent talk at the 2009 Gotham Ruby Conference, Sandi contested that TDD is not enough. Sandi’s talk, which concentrates on applying SOLID design principles in Ruby, is well worth listening to in its entirety.
As Sandi explains, central to SOLID design is avoiding dependencies by striving for code that is:
As she demonstrates applying these principles through refactoring a small Ruby application, Sandi shows that, if we want code to endure in a state that makes it fun to work with, we need to do more than use TDD. As Sandi refactors she emphasises that when we reach a point where the tests pass, we should not be satisfied. Nor should ensuring that the code is DRY be enough. Other questions that need to be asked about the class under test are:
Only when the answer to all of these questions is “yes” should we move on.
I know these are questions I should ask myself more often. As Sandi stresses, “test driven development is good, but it’s not enough.”