Traditionally, the cost of change curve said that if we detect the need for a change early, it costs less to make the change than if we detect the need late. [...]
Our feeling was that the limiting factor on any change was not when it was done, but how much thinking was required. If we made a change during week one, and it took us two days to understand what was really required, it took two days to make the change. If we made a change during week 21, and it took us two days to understand what was really required, it took us two days to make the change.
In week one, we might have had to write 20 statements. In week 21, we might have had to write 20 statements and change four. But if you practice making changes, the time it takes to change four statements is not that great.[...]
Many people are afraid of changes because although they understood the code when they wrote it, that understanding has disappeared. [...] people must be able to look at what they're going to change and understand it.[...]
[...] I hate it when a new requirement comes in that doesn't fit nicely, as if the program were designed to make the requirement hard. In that case, we have a lot of work to do. But the nature of the work is first changing the program so the new requirement is an easy fit, and then doing the easy work to incorporate the requirement. [...] The patch approach means that the next guy who comes along will have to understand both the system that wasn't made to do the new requirement, and the patch that tried to overcome that system without changing it. [...]
Now somebody might say, "Why don't we look forward, look at all the work we have to do? Why don't we design a system that makes all work easy from the beginning?" And if you can pull that off, that's great. It's just that, over and over, people try to design systems that make tomorrow's work easy. But when tomorrow comes it turns out they didn't quite understand tomorrow's work, and they actually made it harder.
I like the notion of working the program, like an artist works a lump of clay. [...] the more she handles the clay, the more the clay tends to do what she wants. [...]
A development team works on a piece of code over several months. Initially, they make a piece of code, and it's a little stiff. It's small, but it's still stiff. Then they move the code, and it gets a little easier to move. In a project I mentioned earlier [in Part II], we added a schema evolution capability to our database. It softened up the program. It was much easier to change. Every time we did a schema change and we got better at it. The programmers and the code—as a unit—softened up. We worked the program, and we kept it flexible.
That bit about schema evolution shows the difference between "all design up-front" versus incremental/iterative design. The "all up-front" approach would try to get the schema right, once, and not necessarily allow for changing the scheme. And of course, at some point, changing the schema is very likely to be necessary - and it will be hard work because it will be done late, with the code assuming that it will never change.