Here’s my contribution to Brad Appleton’s stimulating conversation-piece on simplicity. I’ve produced a number of short soundbites to help understand simplicity, and backed some of them up with concrete examples of how Guardian Unlimited handles its articles.
Brad makes it clear that simplicity is a confusing and often contractory topic. But he’s written his article because
If we can come up with a modicum of modest, simple rules & principles to govern our design decisions in ways that help us minimize and manage interdependencies, eliminate constraints, and remove waste, then we are on the path to solving the real problem and meeting stakeholder needs in a way that is both simple and sustainable.
Strangely, he seems to fall foul of one of the very confusions he’s perceptive enough to identify. He says
The Agile Manifesto defines simplicity as “maximizing the amount of work not done.” But I think that’s a more accurate characterization of Lean than of simplicity.
but then goes on to cross-post his blog entry to several agile and extreme programming groups (1, 2, 3, 4,… thanks to Deborah Hartmann at InfoQ for the links). Indeed, that’s just unfortunate wording in the manifesto. The real issue, as Brad points out, is about complexity, and is something that even proponents of Big Upfront Design would support — indeed, it could be argued that Fred Brooks‘s “surgical team” model of development emphasises a clear vision from a single developer, and therefore produces something uniquely unconfused.
Soundbites on simplicity
For me, it’s the following one-liner of Brad’s that jumps off the screen:
Hiding complexity isn’t the same as removing complexity.
That pithy statement not only sums up many software problems that I’ve come across, it’s also a gem just small enough to fit into my tiny, PowerPoint-addled, brain. Hiding complexity isn’t necessarily wrong, but it is often mistakenly confused with removing complexity and is thus the cause of much pain.
So inspired, I sought to produce some more soundbites. Here’s what I’ve come up with, while trying to avoid agile-specific leanness, or indeed simplicity of user interfaces (say). The observatins below are all about simple design of software, something that should be relevant to any software developer or architect, agile or otherwise. There is some discussion with examples afterwards:
||Minimise the effort to produce results.
||Minimise the effort over the total lifetime.
||Take the most straightforward route.
||Produce the most straightforward result.
||Use existing concepts.
||Use simple concepts.
||Avoid introducing new concepts.
||Avoid introducing concepts new to the problem domain.
||Ensure there are few lines of code.
||Ensure there are few steps to understand the code.
||State the obvious.
||Make it intuitive (to some unspecified person).
||Make it intuitive to a newcomer.
||Obviousness is the first thing you think of.
||Obviousness takes hard work.
Simplicity and time
As Brad says: “…simple and sustainable”. We’ve all been in the situation where a simple hack costs us dear in the long run. It’s called technical debt. The cost of doing something isn’t to be calculated over the immediate future, but over all time.
You can see an example of this with our search engine, which is built on Endeca‘s technology. If you search for “major” you’ll see two kinds of results appear: in the main part of the page you’ll find articles with the word “major” in them, but above those you’ll see links to politicians’ pages (e.g. former prime minister John Major) as well as films with “major” in the title (such as Major League II). Now, the first thing we did with Endeca was create an Endeca thingumy called an “Adapter” which would allow the engine to search articles. But politicians’ details are not stored as articles, they are separate entities in the database. So given that we already had articles being found, how could we best develop the system to fetch politicians’ pages? There were two options.
First we could create another Adapter, but one which allowed Endeca to read politicians’ details. The problem with this is that creating an Adapter takes time, particularly if you’ve only ever created one of them ever before. Additionally, an extra Adapter might be seen as making the search engine more complex. The second option was to allow the underlying database (Oracle) to present politicians’ details as if they were articles, and then Endeca would read them as it did any other articles. This would be quicker because we’ve had years of experience with Oracle against months of experience with Endeca. Also, the search engine software would have remained virtually untouched.
The right answer as far as simple design goes is to choose the first option. It might have taken longer, but it is completely consistent with the existing search engine architecture. The second option might not have increased the complexity of the search engine, but it would have increased the complexity of the database layer and anything that interacted with the politicians’ details. It would have been unintuitive (clever, yes, but unintuitive) and therefore more time-consuming for anyone else to maintain down the line.
We could have chosen the quick-for-now option, but it would have cost us more time in the future.
Simplicity and concepts
This is the section where Brad’s original observation about hiding complexity fits in.
To me, one touchstone of conceptual simplicity is the importance of the domain and domain-driven design. The software problem should relate entirely to its domain. If the domain is complex then the software supporting it will necessarily be complex, but it should be no more so than the problem domain itself. Certainly the software should reflect the problem domain, but it should not bring in any complexities of its own, at least none that infect the domain layer.
A straightforward example of this can be found on the front page of Guardian Unlimited. As we saw above, most of what we produce are, of course, articles. Articles are fundamental to the system. But on the front page you can see a long list of stories, with pictures, links and sometimes little snippets of text. This is called a “trailblock”. When creating something like the front page we could have said trailblocks are just special kinds of articles. This would be the elegant solution, the clever solution, the solution which doesn’t introduce new ideas, and which therefore might be regarded as the simplest solution. But it would also be the wrong solution, because that is not how our journalists think of these things, it is not how they like to manipulate these things, and to contort an article into an unsuitable shape would have caused all kinds of problems.
What we ended up with was a trailblock being an entirely new type of content. As a result we have specialist editing tools (which are quite unlike articles’ editing tools), various ways of rendering them, and extensions such as RSS feeds which would be near-impossible if trailblocks were really just glorified articles. We introduced a new concept, but that concept was only new to the software. It was not new to the problem domain — the world that journalists inhabit.
Simplicity and comprehension
To take another example, I used to work with a wonderfully elegant system (now sadly defunct) which was so pluggable and so configurable that it was often impossible to work out where certain things came from. One day our sysadmin thought he’d like to try his hand at coding, so we gave him a simple job to do: the command line already had a help message, but we’d like it to be a bit more comprehensive. He returned in despair after an hour: “I’ve grepped through the entire source, and I cannot find one instance of the word ‘help’.” Yes, our code was so configurable, even location of the help message was obscured.
Making something appear obvious is hard work, and you don’t get people admiring your work so much because, well, you’ve made it look obvious. But nor do you get people lightly cursing you, such as the developer I know of who delved into a system and discovered that one of his predecessors had named a crucial function “.”. That’s a single fullstop. Clever? Yes. Helpful? Unlikely.
There’s no pithy conclusion to this. I hope the guide above leads us to better understand what simplicity of software involves, and how to distinguish it from its near neighbours. Certainly it’s made me think carefully about a subject I’d previously underestimated.