Over the next few weeks I plan to blog about some agile software architecture and design beliefs that can cause confusion and dissent on agile teams (and angst for project and program managers). Johanna Rothman and I have jointly drawn up a list of misconceptions we’ve encountered as we’ve been working on our new agile architecture workshop. However, I take full responsibility for any ramblings and rants about them on my blog.
The first belief I want to challenge is this: simple designs are always better designs. If you want to quibble, you might say that I am being too strict in my wording. Perhaps I should hedge this claim by stating, “simple design is almost always better”. The corollary: more complex designs are never better. Complex design solutions aren’t as good as a simpler solutions because they are (pick one): harder to test, harder to extend, harder to understand, or harder to maintain.
To break down the old bad habits of doing overly speculative design (and wasting a lot of time and effort over-engineering), keep designs simple. Who can argue against simplicity?
I can and will. My problem with an overly narrow “keep it simple” mindset is that it fosters the practice of â€œkeeping designs stupidly simple. Never allowing time to explore design alternatives before jumping in and coding something that works can lead to underperforming, bulky code. Never allowing developers to rework code that already works to handle more nuances only serves to reinforce ill-formed management decisions to continually push for writing more code at the expense of designing better solutions. What we’ve done with this overemphasis on simplicity is to replace speculation with hasty coding.
Development may appear to go full throttle for a while with thit absurdly simple practice, but for more complex projects, eventually any lack of concerted design effort can cause things to falter. Sometimes more complex solutions lead to increased design flexibility and far less code. But you will never know until you try to design and build them.
One of the hardest things for agile developers is to achieve an appropriate balance between programming for today and anticipating tomorrow. The more speculative any solution is, the more chance it has of being impacted by changing requirements. But sometimes, spending time looking at that queue of user stories and other acceptance criteria can lead you to consider more complex, scalable solutions earlier, rather than way too late. And therein lies the challenge: Doing enough design thinking, coding and experimentation at opportune times.
I don’t see quite how you managed to jump from “keep the design simple” to “never explore alternatives” and “never rework code that works”. I totally agree that those latter two are bad ideas. I just don’t see why you think “keep the design simple” means or implies those things.
Ron, I don’t typically jump from “keep the design simple” to “never explore alternatives” or “never rework code that works”…but many, in my experience do.
In fact, I’ve seen discussions about suitable design solutions grind to a halt when someone throws in this “seems too complex” card on the table. I find it exceedingly annoying when people don’t explore alternatives because they just want to code something and get it working. And in support of keep it simple, exploration is actively discouraged. The focus is on working code, not working designed code. And similarly, when something works, when refactoring to make it support more cases, it often gets more complex…and then some believe that the new design (because it is more complex) is somehow flawed.
I largely agree, also with your answer to Ron. I had a few similar experiences, where potentially better design alternatives weren’t explored because they looked “more complex” (possibly because they were simply “less conventional”). However, this:
“The more speculative any solution is, the more chance it has of being impacted by changing requirements.”
looks just like another myth worth challenging : )
Pingback: Tweets that mention Agile Architecture Myths #1 Simple Design is Always Better - The Responsible Designer -- Topsy.com
Perhaps “simplistic” might be a better term, “simple” design as we all know can be very hard and take several attempts. I think the really killer is buried in the middle paragraph, which is the refusal to fulfil the other half of the incremental design contract and allow deep refactoring when necessary.
I have to agree with Ron here. I personally continue to take issue with a lack of focus on getting code done and working.
Start simple. Then add a story. Many times I will refractor before adding a story to allow for an easy include.
i.e. If I have a block of code that needs to be flexible I might refractor to the open closed pattern. Then when I add the story I only need to write a few lines. In fact I would say it is very common to do a bit of refactoring before a new story, but I would also say that I am often surprised by NOT needing a design.
In short: sketch it out with an implantation. Ink it with refactoring.
Simple helps you sketch quickly, but it only works if you commit to refactoring as well.
Llewellyn- I find it intriguing that you are surprised by NOT needing a design. I’d counter that it seems to me that you ARE designing, and that design is integral to your coding and refactoring. But you don’t need sketches beforehand to see potential solutions.
Oftentimes I work with folks who benefit from sketching out ideas on a whiteboard before they write any code. Otherwise, they don’t see a bigger picture of how things should interact.
If they don’t do that bit of sketching, their code ends up poorly factored and their implementations aren’t very good. I agree with you, focusing on getting code done is and working is what’s important. But not “seeing” any design before coding can cause real problems. Working bad code is no fun to live with. And I am surprised at how hard people who live with really bad code have to work to make even the smallest change. It’s too painful.
I, too, struggle with the assumption that a simple design is always the result of “Never allowing time to explore design alternatives before jumping in and coding”. Many developers and designers work, and think, and even sketch, extremely hard to achieve a simple design. For many, it’s a holy grail, rather than a symptom of “lack of concerted design effort”.
Clearly, “Never allowing developers to rework code that already works” is dumb and goes against all modern programming advice, but it’s a separate matter, and using it to support the first point feels like a non sequitur.
I don’t believe simple design is a wrong-headed goal. Nor that it easy to achieve. But the optimistic belief or the expectation that simple designs are always acheivable in a relatively short timeframe can cause problems.
Just to be clear…I claim that an overemphasis on simple design as a goal may lead you into a tail spin of design fretting if you don’t have a strong value of making code work….or, it may lead you to discount more complex (but scalable solutions) as being too complex, or even keep around bulkier simple code (rather than trying to refactor) if you don’t give people time to think things through and experiment.
Your post is so awesome! Once again you have articulated the subtle nuances of the act of software development for the rest of the world to learn. Keep it simple is akin to Getâ€™er done here in the Southeast. I get dogged for suggesting that not enough time is spent even analyzing a problem yet alone designing a solution. So far, I have never been in a shop where anyone even seems to know or care about OOAD. All they want is working code that sucks! There is no beauty, no process, no method, no form, and no quality, itâ€™s all accidental.
I agree with Daniel. Many places I’ve worked or consulted at, the norm is “Ready, Shoot, Aim.” Even when projects are billed as a total make-over, they often don’t touch the more complex appearing aspects of the old system – usually the persistent and/ or domain layers. Instead the presentation layer is just reworked – lipstick on a …
I have, however, been associated with shops where OOAD is a valued activity. I remember a comment that a friend once told me, “Once you work for an organization with a mature OOAD methodology, you’re never willing to go back to the OK Corrall style of software development.
A simple design, on a complex problem, is, always (at least for those of us that are not exceptional genius), the final iteration of several complex designs, if not, it is not simple, its just sloppy. Simplicity is the ultimate sophistication, You will seldom achieve it and never without hard work.
As Mencken puts it :
“For every complex problem, there is a solution that is simple, neat, and wrong.”
Henry Louis Mencken (1880 – 1956)