Summary
This chapter attempts to give you a feel
for the broad issues of object-oriented programming and C++, including why OOP
is different, and why C++ in particular is different, concepts of OOP
methodologies, and finally the kinds of issues you will encounter when moving
your own company to OOP and C++.
OOP and C++ may not be for everyone.
It’s important to evaluate your own needs and decide whether C++ will
optimally satisfy those needs, or if you might be better off with another
programming system (including the one you’re currently using). If you know
that your needs will be very specialized for the foreseeable future and if you
have specific constraints that may not be satisfied by C++, then you owe it to
yourself to investigate the
alternatives[24].
Even if you eventually choose C++ as your language, you’ll at least
understand what the options were and have a clear vision of why you took that
direction.
You know what a procedural program looks
like: data definitions and function calls. To find the meaning of such a program
you have to work a little, looking through the function calls and low-level
concepts to create a model in your mind. This is the reason we need intermediate
representations when designing procedural programs – by themselves, these
programs tend to be confusing because the terms of expression are oriented more
toward the computer than to the problem you’re solving.
Because C++ adds many new concepts to the
C language, your natural assumption may be that the main( ) in a C++
program will be far more complicated than for the equivalent C program. Here,
you’ll be pleasantly surprised: A well-written C++ program is generally
far simpler and much easier to understand than the equivalent C program. What
you’ll see are the definitions of the objects that represent concepts in
your problem space (rather than the issues of the computer representation) and
messages sent to those objects to represent the activities in that space. One of
the delights of object-oriented programming is that, with a well-designed
program, it’s easy to understand the code by reading it. Usually
there’s a lot less code, as well, because many of your problems will be
solved by reusing existing library
code.
2: Making & Using Objects
[4]
See Multiparadigm Programming in Leda by Timothy Budd (Addison-Wesley
1995).
[5]
You can find an interesting implementation of this problem in Volume 2 of this
book, available at www.BruceEckel.com.
[6]
Some people make a distinction, stating that type determines the interface while
class is a particular implementation of that interface.
[7]
I’m indebted to my friend Scott Meyers for this term.
[8]
This is usually enough detail for most diagrams, and you don’t need to get
specific about whether you’re using aggregation or
composition.
[9]
An excellent example of this is UML Distilled, by Martin Fowler
(Addison-Wesley 2000), which reduces the sometimes-overwhelming UML process to a
manageable subset.
[10]
My rule of thumb for estimating such projects: If there’s more than one
wild card, don’t even try to plan how long it’s going to take or how
much it will cost until you’ve created a working prototype. There are too
many degrees of freedom.
[11]
Thanks for help from James H Jarrett.
[12]
More information on use cases can be found in Applying Use Cases by
Schneider & Winters (Addison-Wesley 1998) and Use Case Driven Object
Modeling with UML by Rosenberg (Addison-Wesley 1999).
[13]
My personal take on this has changed lately. Doubling and adding 10 percent will
give you a reasonably accurate estimate (assuming there are not too many
wild-card factors), but you still have to work quite diligently to finish in
that time. If you want time to really make it elegant and to enjoy yourself in
the process, the correct multiplier is more like three or four times, I
believe.
[14]
For starters, I recommend the aforementioned UML
Distilled.
[15]
Python (www.Python.org) is often used as “executable
pseudocode.”
[16]
At least one aspect of evolution is covered in Martin Fowler’s book
Refactoring: improving the design of existing code (Addison-Wesley 1999).
Be forewarned that this book uses Java examples exclusively.
[17]
This term is explored in the Design Patterns chapter in Volume
2.
[18]
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 produced messy systems that were expensive to
maintain.
[19]
Although this may be a more American perspective, the stories of Hollywood reach
everywhere.
[20]
Including (especially) the PA system. I once worked in a company that insisted
on broadcasting every phone call that arrived for every executive, and it
constantly interrupted our productivity (but the managers couldn’t begin
to conceive of stifling such an important service as the PA). Finally, when no
one was looking I started snipping speaker wires.
[21]
I say “may” because, due to the complexity of C++, it might actually
be cheaper to move to Java. But the decision of which language to choose has
many factors, and in this book I’ll assume that you’ve chosen
C++.
[22]
However, look at Dan Saks’ columns in the C/C++ User’s
Journal for some important investigations into C++ library
performance.
[23]
Because of its productivity improvements, the Java language should also be
considered here.
[24]
In particular, I recommend looking at Java (https://java.sun.com) and Python
(https://www.Python.org).