Iteration is where your program goes from good to great, and where those issues that you didn’t really
understand in the first pass become clear. It’s also where your classes can evolve from single-project usage to reusable resources.
What it means to “get it right” isn’t just that the program works according to the requirements and the use-cases. It also means that the internal structure of the code makes sense to you, and feels like it fits together well, with no awkward syntax, oversized objects or ungainly exposed bits of code. In addition, you must have some sense that the program structure will survive the changes that it will inevitably go through during its lifetime, and that those changes can be made easily and cleanly. This is no small feat. You must not only understand what you’re
building, but also how the program will evolve (what I call the vector of change). Fortunately, object-oriented programming languages are particularly adept at supporting this kind of
continuing modification – the boundaries created by the objects are what tend to keep the
structure from breaking down. They are also what allow you to make changes – ones that
would seem drastic in a procedural program – without causing earthquakes throughout your
code. In fact, support for iteration might be the most important benefit of OOP.
With iteration, you create something that at least approximates what you think you’re
building, and then you kick the tires, compare it to your requirements and see where it falls short. Then you can go back and fix it by redesigning and re-implementing the portions of the program that didn’t work right.12 You might actually need to solve the problem, or an aspect
of the problem, several times before you hit on the right solution. (A study of Design
Patterns, described in Chapter XX, is usually helpful here.)
Iteration also occurs when you build a system, see that it matches your requirements and then discover it wasn’t actually what you wanted. When you see the system in operation, you find that you really wanted to solve a different problem. If you think this kind of iteration is going to happen, then you owe it to yourself to build your first version as quickly as possible so you can find out if it’s what you want.
Iteration is closely tied to incremental development. Incremental development means that you start with the core of your system and implement it as a framework upon which to build the
rest of the system piece by piece. Then you start adding features one at a time. The trick to this is in designing a framework that will accommodate all the features you plan to add to it.
(See Chapter XX for more insight into this issue.) The advantage is that once you get the core framework working, each feature you add is like a small project in itself rather than part of a big project. Also, new features that are incorporated later in the development or maintenance 12 This is something like “rapid prototyping,” where you were supposed to build a quick-and-dirty version so that you could learn about the system, and then throw away your prototype and build it right.
The trouble with rapid prototyping is that people didn’t throw away the prototype, but instead built upon it. Combined with the lack of structure in procedural programming, this often leads to messy systems that are expensive to maintain.
Chapter 1: Introduction to Objects
54
phases can be added more easily. OOP supports incremental development because if your program is designed well, your increments will turn out to be discrete objects or groups of
objects.
Perhaps the most important thing to remember is that by default – by definition, really – if
you modify a class its super- and subclasses will still function. You need not fear
modification; it won’t necessarily break the program, and any change in the outcome will be
limited to subclasses and/or specific collaborators of the class you change.