This article provides an overview of the elements of C++; specifically, the 'C' portion of C++.
Note how section 2.2 describes tokens as the "minimal chunks of a program". The root goal of programming is solving problems using the 'chunks' of a programming language. Of course, the chunks must be appropriate for the type of problems to be solved. Generally, smaller chunks are applicable to many types of tasks, but involve more effort; larger chunks involve less effort, but are designed for more specific tasks.
Analysis and design
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 you've actually built a pristine program and all you need to do is
change parts, oil it, and keep it from rusting. Perhaps there's a better
term to describe what's going on.
I'll use the term evolution.
That is, "You won't 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 you'll 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
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 also allow you to make changes – ones that
would seem drastic in a procedural program – without 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 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. 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 Volume 2, is usually helpful here).
Evolution
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 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 default – by definition, really – if you modify a class then 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 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.