Architect's Dilemma: Designing Up-Front?
Do you ever feel that sometimes designing up-front makes sense? Does it feel like a more organized, more controllable way of working? Does it ever make sense to design up-front?
Agile-istas dismiss the BDUF - or Big Design Up-Front. They claim it's impossible to know up-front what the application will look like, and the entire effort becomes too costly and does not produce enough value in return. Some agile-istas dismiss the idea of designing software up-front entirely in response. This argument has been popular for many years and promoted heavily by agile mongers.
Yet dismissing design efforts entirely is often not a good idea. I believe that designing some components in an application up-front is a better alternative than to dive in and code your way out of it. And the best reason to consider designing some components up-front is to achieve better code quality, avoid costs and achieve it with less effort.
Most code bases I've reviewed that were created by agile teams had bad code quality. Not only were their metrics off the scale, their software did not have any components. All code resided in one or a few projects. Yet having separate projects is a great way to maintain an overview of how components depend on each other. If your dependency graph between projects looks like a plate of spaghetti you know something's wrong.
Let me use an example of a common architectural component that can very well be designed up-front: a client interface with a vendor's web services. The web service operations I have in mind consist of two groups:
- Synchronous operations: a response is returned immediately.
- Asynchronous operations: a response is returned at a later time.
The application I have in mind has to provide an abstraction for these web service operations since they will be called from different parts of the application. There are some extra requirements:
- Asynchronous requests have to be retried if the web service is not available.
- If subsequent retries keep failing the calling component in the application has to be notified and the request has to be abandoned.
- The calling component in the application has to be notified of technical and functional errors returned by the web service.
- If no response is received for asynchronous requests after a certain period of time the requests have to be abandoned and the calling component in the application has to be notified of this.
These are clear requirements imposed by the customer. There's an opportunity here to make a good design and take into account code quality in the design phase. For example:
- Synchronous, asynchronous request and asynchronous response handling could be separated in three projects that have no inter-dependencies.
- Callback interfaces could be designed for the calling components to implement. These decouple the web service interface logic from other parts of the application.
- The technical requirements like timeout detection and retry policies could remain hidden for other components in the application.
Designing the web service interface component up-front does not imply that other parts of the application also need to be designed up-front. Here are the most obvious advantages of designing this component up-front:
- The implementation of the interface component becomes easier to understand up front thanks to a design effort.
- The design can enforce better code quality.
- Design documents should take no more than one day to complete. They can be reviewed, also by those critical of upfront design. This should guarantee a better understanding of the tasks ahead than code/test/refactor iterations alone can provide, actually reducing the cost of the web service interface component.
- A design effort can rationalize team discussions about application behavior. It also allows to reconcile certain functionality with other objectives like estimation, code quality or architectural integrity.
In general, I think it's unwise to systematically dismiss design up-front. Some component may benefit from this. This does not mean all parts of an application have to be explicitly designed up-front. However, there is value in trying to get an agreement from your most critical team members.
This can mean they have to prove a design up front is not required. It can also mean you have to prove to them a design up-front for certain components is a winning strategy.
Happy architecting!
- Login or register to post comments
- 1017 reads
- Flag as offensive
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)







Comments
Tim Goeke replied on Sat, 2008/02/16 - 3:54pm
I think that projects go a lot better if there are plans up front. Joel has an article about this in which the speedy coder jumps into the project and then ends up taking longer than the planning coder.
I think there is some truth to this, in the sense that "failing to plan is the same as planning to fail". This may be first attributed to Ben Franklin, but I'm sure the idea goes back a long way, certainly it's got a few hundred years on the computer revolution.
There's a counter point that must also be considered, "No plan can survive contact with the enemy." This is attributed in it's various forms to the Moltke the Elder, widely considered to be the father of modern warfare.
If the anology can be carried forward, and I think it can, then you must have a balance of planning and execution. You have to get your plan into the battle so you can make adjustments.
Being agile does not free one from making plans, rather, it means that one must plan in correct proportions knowing that much of any plan will be thrown away. But in preparing the plan, you consider options that may not have occurred to you. And you should have contingency plans. Reading about von Moltke can be educational:
- He was effective despite the failings of his superiors.
- He knew many languages.
- He knew how to use resources.
- He knew how to adjust when things didn't go according to plan.
Seems like he would have made a great software developer. ;-)
Tim Goeke replied on Sat, 2008/02/16 - 4:00pm
Just to clarify, planning should take a couple days and result in marker board photos and maybe 5-20 pages describing the plan including use cases.
I am starting to like Version One as an agile planning tool, to start tracking.
You have to also re-plan fairly often if the requirements change. There's nothing wrong with taking the team for a 2-3 hour circle the wagons planning session. Just marker board everything, use your digital camera. You can even use an eye-fi to upload the images very easily.
Rainer Eschen replied on Sat, 2008/02/16 - 6:15pm
What's wrong with planning? What's wrong with design? My experience shows that all guys that renounce this get worser results.
One important point to this: even a plan is part of the documentation that can help (new) team members to understand what's going on. We all know what's going on when documentation is missing ;-). let's invest time so that we not waste time in the end.
For me agile is, to do all this in short iterations. Maybe on a weekly or daily basis.
Springsteam Blog - Next Generation Java Development
Sharath replied on Thu, 2008/04/03 - 3:17am
Ben Northrop replied on Mon, 2008/04/07 - 4:08pm
I posted on this topic a few months back, with the same title interestingly enough:)
http://www.bennorthrop.com/Home/Blog/2008_01_20_decision_tree.php
I don't think either strategy - design up front or in-time design - can be systematically disregarded. That's what makes this problem tough...and contentious. Certain environments, problems, technologies, etc. demand more rigor/up-front thought. In some environments, extensive up-front design is just not a possibility unfortunately - for example when your company is going to go out of business if it doesn't release the software to the client in 2 weeks. It's not the ideal...but it's the reality...
Regarding agilists and sloppy code...I think the real hard-core advocates might argue that the principles of agile development (e.g. continuous integration, refactoring, unit testing, etc.) support, not thwart, clean code.
Just my 2 cents. Good thoughts.
nicoduka replied on Wed, 2008/05/07 - 11:54am
Design up-front vs. along-the-way
I had a discussion at lunch yesterday about the right way to do design.
Waaaaaay back when I was in school - when Van Halen's "Jump" was at the top of the charts - we were introduced to the Waterfall Model of software development. (aside - it Royce's model was iterative, but it was rarely discussed that way - the typical discussion broke the whole project down into phases).
Anyway, the waterfall model (and some other models as well) have distinct phases. In waterfall, you first collect requirements, then you design, then you implement, etc.
I've never found that to be very workable. As Field Marshal Helmuth von Moltke said, "No plan survives contact with the enemy" (actually, what he said was, "No operation plan extends with any certainty beyond the first encounter with the main body of the enemy" (though he likely said something like "Kein Betrieb Plan verlängert mit jeder möglicher Sicherheit über dem ersten Treffen mit dem Hauptkörper des Feindes hinaus" (or at least that's what he would have said if he spoke English and used Babelfish...)))
That doesn't mean that you should have a design, it just means that you should expect your design to change along the way as you learn more. But without spending time on design, you are likely to make some errors of architecture that will be difficult or costly to fix.
And just going off and starting coding would not have been tolerated by Tony Jongejan, my high school programming teacher.
At least that's what I used to think. These days, I'm not so sure, for most applications (see caveats later).
The problem is that, unless you've already built such a program (some of which is codified in the prototyping and "build one to throw away" schools of thought), you rarely have enough information to make informed choices, and you won't have that data until you actually write the code.
I think that you're far better off if you focus on building clean and well-architected (at the class level) code that has good unit tests, so that you'll have the ability to adapt as you learn more. It's all about the resiliency of the source to the change that is going to come, and letting the code evolve to do what it needs to do.
Caveats? Well, there are a few.
If you're in the library business, you will at some point have to put a stake in the ground and ship the thing, which will severely constrain further modifications. Your library may also be used in ways you didn't imagine.
I think the right way to solve that is with a little design up front, a lot of prototype use, and then a good review process before you ship it.
So what do you think? What amount of design is right before coding?
______________________________
Submited by : Dietas