Under-Design and Over-Design
One of the biggest challenges I’ve had in my career as a developer was over-design. I used to just dive in and code on projects but soon afterwords I would end up stuck. To compensate I would spend a lot of time in the design phase only to discover later that most of my concerns never needed to be addressed and so my effort were wasted.
How much design is too much design? I’ve often asked this question and came to various conclusions in my 30 year career as a developer.
Today, most of the people I work with know me as a patterns guy. Design patterns are one of the most powerful tools I’ve come across and I use them a lot. I’m a big believer in patterns so this may come as a surprise but the more development I do the less (up front) design I do.
I still do design but I just do it as I go so that my designs can emerge. I know it must be a bit unnerving for people to talk about emergent design if you’ve never experienced it. Software development is expensive and error prone so I wouldn’t like the idea of putting off important decisions until later if I also had to pay a big price later. But knowing how and what to defer so that I don’t have to do a lot of reworking later can be a valuable practice.
It turns out that most design details do not need to be worked out up front and if we try to work them out up front we often end up locking ourselves in to a particular implementation that may make it difficult to change later. These tend to be poor decisions because they are often made in isolation from the rest of the system, plus we may not know enough yet to make the right choice.
Using risk mitigation techniques and some basic practices of encapsulation we can hide important decisions so we can resolve them later without a lot of rework. I teach several of these techniques in my training because they are some of the most important skills for an agile developer. They allow you to eliminate external dependencies and let you hide your thorniest issues behind a well define interface so they they can be changed later without impacting other parts of the system.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





Comments
Alan Roche replied on Thu, 2010/12/16 - 12:41pm
An interesting question and one I often ask myself also. Its often difficult to get the balance right.
I think Martin Fowler describes the "Blueprint" versus "Sketch" design analogies. He suggests that unlike say a civil engineering project the sketch design approach is often better suited for software development.
I think I find myself taking the sketch design approach generally. Over the years I've learned that as you get deeper into the implementation details, its too common for any "preconceived" designs to go out of the window, resulting in this wasted work that you describe. My preference is towards keeping to a sketch design up front, with good separation of concerns etc. such that refactoring later isn't a huge drama, and time is available to do it. I think the inordinate time that can easily get sucked into upfront, blueprint design (analysis paralysis anyone) is better spent on judicious refactoring later.
Jose Maria Arranz replied on Thu, 2010/12/16 - 1:55pm
In my opinion you are not talking about "over-design", you are talking about "premature-design", very different.
Premature-design is when you try to design the most you can before coding... and as you know it usually ends bad.
Rarely you are going to find "over-design", because over-design requires too much time, over-design is when you make too much abstractions, when you reuse too much and this is not the case in this crazy world, most of the time you are going to find "ever-over-draft" code :)
I'm sure that with your very long experience (happy to read a guy with so long experience) you are almost the only guy doing "over-design" ;)
Jason Kilgrow replied on Tue, 2010/12/21 - 10:44am
in response to:
Jose Maria Arranz