Phase 5: Evolution
This is the point in the development cycle that has traditionally been called maintenance, a catch-all term that can mean everything from getting it to work the way it was really supposed to in the first place to adding features that the customer forgot to mention to the more traditional fixing the bugs that show up and adding new features as the need arises. So many misconceptions have been applied to the term maintenance that it has taken on a slightly deceiving quality, partly because it suggests that youve actually built a pristine program and all you need to do is change parts, oil it, and keep it from rusting. Perhaps theres a better term to describe whats going on.
Ill use the term evolution. That is, You wont get it right the first time, so give yourself the latitude to learn and to go back and make changes. You might need to make a lot of changes as you learn and understand the problem more deeply. The elegance youll produce if you evolve until you get it right will pay off, both in the short and the long term. Evolution is where your program goes from good to great, and where those issues that you didnt really understand in the first pass become clear. Its also where your classes can evolve from single-project usage to reusable resources.
What it means to get it right isnt 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 youre 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 modificationthe boundaries created by the objects are what tend to keep the structure from breaking down. They also allow you to make changesones that would seem drastic in a procedural programwithout causing earthquakes throughout your code. In fact, support for evolution might be the most important benefit of OOP.
With evolution, you create something that at least approximates what you think youre 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 reimplementing the portions of the program that didnt work right. 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 is usually helpful here. You can find information in Thinking in Patterns (with Java) at www.BruceEckel.com.)
Evolution also occurs when you build a system, see that it matches your requirements, and then discover it wasnt actually what you wanted. When you see the system in operation, you may find that you really wanted to solve a different problem. If you think this kind of evolution 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 is indeed what you want.
Perhaps the most important thing to remember is that by defaultby definition, reallyif you modify a class, its super- and subclasses will still function. You need not fear modification (especially if you have a built-in set of unit tests to verify the correctness of your modifications). Modification wont necessarily break the program, and any change in the outcome will be limited to subclasses and/or specific collaborators of the class you change.