Do you remember when you first programmed? I remember how I could type a few statements, debug a bit, and the machine would respond. It was easy to get the computer to do something, as it was easy to change it. After all, the whole point of software was to be soft.
It is not that it is hard to change software, it`s just hard to change the software without it breaking.
Of course, the changeability of software was an illusion. Or rather it is not that it is hard to change software, it`s just hard to change the software without it breaking.
This problem is something software people have known about for a long time. It is why doing ad hoc design - designing as you go about building a program - doesn`t work for larger scale systems.
To resolve this problem, software developers took inspiration from other branches of engineering where there is a clear separation between the design process and the construction process.
This idea underpins most of the methods in software development. Instead of ad hoc design we have "up-front design". Here the designers make design decisions before those decisions are programmed. The design should not change significantly after programming has started.
The difficulty is getting these designs close enough so you don`t have any significant changes that cause the design to deteriorate. This is where practical problems start appearing. One is the difficulty of getting a design right at the start.
The reality of changing requirements
But there is a more fundamental problem. When I visit projects that have gone awry, to see if there is a way out of trouble, I talk to the developers and I always seem to get the same lament: "The users keep changing the requirements."
I`m always surprised that anyone is surprised by changing requirements. I`ve never come across a serious project where requirements don`t change. You can get users to sign off requirements documents in every blood group, but they still change their mind.
It is very hard to visualise what a computer system will look like. Businesses change, and a very important requirement becomes minor. Exacerbating this is that users think it is easy to change software. The challenge is that we need to be better at getting requirements right in advance. I used to believe that too, but now I`ve come to the conclusion that it is unreachable, at least for a while.
The balance of wants and costs is key here. We cannot expect our users to fix requirements until we can estimate costs with reasonable accuracy. We are bad at cost estimation as our basic materials keep changing. Civil engineers would find it difficult to estimate if the fundamental properties of concrete kept undergoing a major "upgrade" every year.
It comes down to expecting requirements to change and using a development process that relishes change. That strikes at the core of the upfront design process. If requirements change without warning, how can we develop a stable upfront design?
Making change easier
The answer is to build software so that it is more able to deal with unanticipated change. Objects are key and by using them with encapsulation and polymorphic interfaces we can improve the packaging of our software, reducing dependencies and making things easier to change.
For many professional developers dynamic development tools are still new, but it makes a great difference when you can edit code in a debugger and have the change made instantly.
Refactoring, a set of techniques that let you change the design of software efficiently without introducing bugs, plays a big role. If you get a design wrong you can change it later without incurring huge cost.
Dynamic design
All of these techniques point towards a shift in how we approach design, moving towards a style I call "dynamic design". You don`t try to get the design right at the beginning. Instead all you want is some reasonable solution. As you build the solution, you understand more about the problem, and that the best solution is different from the original solution. With refactoring, objects and a dynamic environment, it is no longer expensive to make changes.
An important result is a greater move towards simplicity of design. Since design changes are expensive, aim at building a design that will stand up to foreseeable changes. The problem is that flexibility costs. Flexible solutions are more complex and more expensive to maintain, although easier to flex in a different direction. The big frustration is that all this flexibility is not needed and it`s impossible to predict what is needed. So to gain the flexibility, you have to put in a lot more flexibility than you need.
With dynamic design you approach the risks of change differently. You still think about potential changes and consider flexible solutions. Instead of implementing them you ask "how difficult is it going to be to change a simple solution into the flexible solution?". If the answer is "pretty easy" then you implement the simple solution.
So dynamic design leads to simpler designs, without sacrificing flexibility. With a broad sense of those things that refactor easily, you don`t even think of the flexible solutions. As Kent Beck puts it: you build the simplest thing that could possibly work. As for the flexible, complex design: most of the time you aren`t going to need it.
That`s quite a change in design process, and it`s been a big shift for me as a designer. It has several pre-conditions. You need good tests, you need objects, you need to know how to refactor. But the reward is the ability to put away the fear of changing requirements and to be responsive to your users without sacrificing your design, and thus your future.
- ObjectActive 99 is sponsored by Software Futures and Sun Microsystems. It will be held in Johannesburg at the VW Conference Centre from 22 to 24 June and in the Cape at Table Bay Hotel from 29 June to 1 July. For further information, contact Derek Hughes on (011) 807-1340 or derekh@softwarefutures.com or visit the Web site at www.objectactive.co.za.

