Ron Burk has a BSEE from the University of Kansas and has been a programmer for the past 10 years. He is currently president of Burk Labs, a small software consulting firm.
He may be contacted at Burk Labs, P.O. Box 3082, Redmond, WA 98073-3082.
C++ is a language that allows object-oriented programming, but which does not cater to it exclusively; C++ supports other styles of programming as well and is not typically regarded as a "pure" object-oriented language. Nevertheless, the surging popularity of both C++ and object-oriented programming is forcing object-oriented purists who favor Smalltalk and similar programming languages to turn to C++ to express their ideas. One result of this phenomenon is Mark Mullin's new book: Object Oriented Program Design With Examples in C++.
The book attempts to capture the design and implementation of a realistic project: building a corporate database for a fictitious client, the Bancroft Trading Company. Among the items constructed are a customer database, a supplier database, a sales database, and an inventory system. The first half of the book concerns itself with design and tries to avoid language-dependent issues. The second half of the book focuses on the specifics of implementing the design in C++. Only part of the code that would be necessary to implement the design is supplied, but several of the object classes are presented in some detail.
The author did not intend the book to be an introduction to C++, although half of the book is devoted to implementing object-oriented designs in C++. For example, designing object classes in C++ requires attention to the fact that they will interact with other data types [1], but problems like that are only mentioned in passing. Also, the additions to the language brought by version 2.0 are not reflected in the book. For example, abstract classes are discussed but the new language facilities for implementing them are not. In other words, you should not look to this book for the best examples of C++ usage; the focus of the book is at a higher level.
The author chose an excellent framework for a book on object-oriented design; much of the impetus behind the object-oriented movement is its promise of simplifying the design, implementation, and maintenance of large software systems. Discussions of object-oriented design that use small examples for illustration tend to be unrealistic and unenlightening. If you're learning C++ or object-oriented programming, you've probably already seen your share of examples such as using a class Car to derive sub-classes Jeep and Maserati. Unfortunately, most of us can't make a living writing programs that implement automobile taxonomy.
The author had another good idea when he decided to present a realistic design process, rather than a completed, polished design. In real life, you usually are not handed a complete, clear set of program requirements at the beginning of a project. Instead, you may have to ferret out the requirements for yourself and some may appear at inopportune moments, forcing you to revise work already finished. Presenting a complete, polished product does not reveal the tortuous path that led to it. The author made a conscious effort to present the process, rather than the result, of object-oriented design.
Solving a realistic problem with object-oriented design is important because books about design methodology all too often select problems that are tailored to the methodologies' particular strengths. Although the book tackles a realistic design problem, its solutions are often not as down-to-earth. For example, the analysis in the book doesn't try to estimate hardware requirements for the completed system or investigate the expected number of data items; a large database requires more attention to efficient access methods than a small one. Also, a significant amount of realism is sacrificed by assuming that the database to be implemented will fit in memory; the implementation ignores file I/O, record locking, and related headaches.
One plus for the book is that it is more balanced in its view of object-oriented programming than other treatises. There is the occasional lapse, such as offhand promises of reusability, but you can also find passages such as "object oriented design is not a panacea" and an admonition to view object-oriented as "an extension of proven techniques". As you study object-oriented programming books, you have to be ready to separate useful information from mere hype.
Rather than introduce object-oriented design as a step-by-step, rigorous methodology, the book presents object-oriented solutions as common-sense responses to real problems in its case study. This style can be effective (as it was in Software Tools, by Kernigan and Plauger), but it requires careful writing, trying to match each design issue with the problem that can best illustrate it and describing the alternatives that weren't chosen as adequately as those that were. Object Oriented Program Design doesn't always succeed in making its points clear.
The common-sense advice in the book occasionally becomes so vague as to appear contradictory. An example worth detailing relates to whether, and under what circumstances, it is acceptable for an object to have an internal state that affects its behavior. The summary of Chapter 1 states, "Objects behave in a uniform fashion, without regard to the data they contain." On the other hand, the summary of Chapter 2 states, "Objects may behave differently because of their contents." It is possible to interpret these statements in a non-contradictory way, but that is made more difficult by an early object class design example: Collections.
A Collection object is intended to be a general-purpose collection you can put objects in the collection, delete objects from the collection, and examine the objects in the collection. Examining the objects is accomplished by making the Collection object class keep track of a "current" object in the collection and implementing operations such as "get current", "get first", and "get next". This has an unfortunate side effect: a function that accesses a Collection and calls another function which accesses the same Collection may find its "current" place in the Collection unexpectedly changed. Nothing in the book indicates whether the author considered this limitation and it casts doubt on whether he actually intended to say that an object's behavior should not depend on the data it contains.
The case-study approach of the book complements, rather than replaces, more theoretical discussions of design. It is unfortunate, then, that the author included no references. A bibliography would have supplied insight into how the ideas in the book evolved and provided the opportunity to study particular ideas in more detail.
The book's C++ implementation is modelled after Smalltalk-like languages and other styles of usage are not explored. The author discusses weakly-typed versus strongly-typed systems, but some interesting issues are untouched. Choosing between a class hierarchy with a single root and a forest of classes, for example, is a very relevant issue to C++ programmers, since C++, unlike Smalltalk, does not encourage one choice over the other. The GNU C++ library [2] is a current example of the latter style while the OOPS library [3] is a well-known example of the former. It would have been interesting to read the author's comments on this ongoing discussion.
It is customary in technical books for the author to credit the editor and technical readers for the correct passages in the book and absolve them of any blame for the errors. In Object Oriented Program Design, however, the editor and technical reader let the author down in a couple of respects. First, programmers deserve books with correct spelling, punctuation, grammar, and consistent voice and the editor missed many instances of these faults in the book. Typographical errors in program code are especially irritating when you're studying a new language. Second, the technical reader should have objected to the clumsier uses of C and C++. For example, the following expression was used in lieu of the left-shift operator:
(int) pow((double)bitNo, (double)2)In another example, two nearly identical functions are defined rather than simply creating one with a default argument (a C++ language feature).
Summary
Although the book is blessed with good ideas, it is cursed with their flawed execution. The result is still worth reading, but falls short of its potential. If you are a C programmer learning C++, this book is a good way to get a feel for the pure object-oriented approach to using the language, but you should be aware that this is not the only useful style, nor is the language used to best advantage in the examples. I like the author's ideas very much and I hope he writes another book that carries them further.
References
[1] Murray, R.B., Building Well-Behaved Type Relationships in C++, Proceedings, USENIX C++ Conference, 1988.[2] Lea, Douglas, libg++, The GNU C++ Library, Proceedings, USENIX C++ Conference, 1988.
[3] Gorlen, Keith E., An Object-oriented Class Library For C++ Programs, Proceedings, USENIX C++ Conference, 1987.
Object Oriented Program Design With Examples In C++
Mark Mullin
Addison-Wesley 1989
$19.95, 320 pages.