Dr. Dobb's Journal December 1998
In general, I look for books that will make good texts for the introductory object-oriented courses I teach for both universities and corporations. My main goal is to find a book that clearly and correctly presents the basic aspects of the object-oriented approach. This means a good discussion of analysis, design, and implementation. Over the years, I've used Object-Oriented Modeling and Design, by James Rumbaugh et al. (Prentice-Hall 1991). Alas, it has become somewhat dated, so I've been looking for a more up-to-date stand-in.
One book I've considered as a replacement is UML Distilled, by Martin Fowler. (UML, short for the "Unified Modeling Language," has been adopted as a standard by the Object Management Group and many other organizations. Essentially, UML is an analysis and design notation with corresponding semantics that can be applied to develop systems in many different ways.) The objective of UML Distilled is to show the application of the language. It is a slim book -- only 171 pages of text -- and you'd expect its real estate to be well used. However, the first 42 pages contain a rather rambling discussion of process aspects that is not very relevant in a book about UML. UML itself only starts in Chapter 4, and each type of diagram is introduced with a simple example. Here again, Fowler wastes space explaining basic concepts such as classes, attributes, generalization, and so on. If you already know object-oriented concepts, this coverage is superfluous; if you don't, it is too superficial to be of value. Some concepts (invariants, constraints, and the like) are defined but not illustrated. There is almost nothing about design and very little about implementation.
Furthermore, UML Distilled contains some errors. For example, the use of an association (relationship) in an example of purchase orders is not quite correct -- order lines are components of order, not just related to it. This is important because lines don't have their own life -- they depend on the order. This is a common misuse of aggregation. Likewise, the patient observation model in Chapter 11 is hard to understand without a more detailed discussion of its context. The references include mostly books. The most interesting chapter is Chapter 9, which discusses Activity diagrams, a topic not usually found in an introductory textbook (activities are valuable for descriptions of use cases and for real-time applications).
In summary, while UML Distilled does a reasonable job of presenting basic UML concepts, it doesn't go much further than the UML documents published on the Web by companies such as Rational. If you know OMT or a similar notation, moving to UML is straightforward; if you don't, this book will not help.
Applying UML and Patterns, by Craig Larman, is much more ambitious -- it attempts to introduce analysis and design using UML and design patterns. It assumes a basic knowledge of object-oriented concepts.
There is a good discussion of use cases (two chapters), a fairly good examination of analysis, and decent coverage of design aspects, including the Model-View-Controller (MVC) architecture. UML is used throughout, and all its important aspects are discussed and illustrated. The example design goes through two iterations to be more realistic. There is even a discussion of persistence aspects. Applying UML and Patterns is the only book I examine here that uses patterns and incorporates them in the design of a realistic example. In general, the level is serious and I could not find any obvious errors.
A peculiarity of Applying UML and Patterns is its use of collaboration diagrams instead of sequence diagrams. While collaboration diagrams are useful in many situations, they do not show the sequence between messages, which in most applications is very important. In fact, sequence diagrams can include time annotations, which make them useful in real-time applications. To be honest, I never was able to figure out the reason for Larman's preference. Since state diagrams are barely used, I'd say that dynamic aspects are neglected in this book. Aggregation is not introduced until page 359. I was surprised that such a basic modeling concept is considered "advanced." In fact, it is frequently misused (as in the aforementioned case), and the references (to books only) are barely adequate.
UML and C++, by Richard C. Lee and William M. Tepfenhart attempts to provide a basic introduction to object-oriented concepts. For this, the authors purposely leave out patterns, which they consider an advanced topic. Their implementation discussions are based on C++; other languages are barely mentioned. There is also a clear emphasis on CRC cards, which provide a useful way to find objects, especially for people who don't have much experience. The book provides no discussion of relationship classes or statecharts, only a few pages devoted to state diagrams, and almost no mention of architectural aspects. UML, although part of the title, is not used in all its possibilities.
Lee and Tepfenhart's style is direct and the explanations are clear. They also include a chapter on implementing relationships, an important subject that I have found discussed only in Rumbaugh's ObjectOriented Modeling and Design. Perhaps the strongest point of this book is the complete case study (a video game), which takes four chapters and 167 pages. This is useful for those new to the approach, since this example illustrates how all the concepts fit together.
Use Cases Combined with Booch/OMT/ UML, by Putman P. Texel and Charles B. Williams, presents a step-by-step process to develop object-oriented applications. The authors assume you already know basic OO concepts. Despite this premise, they include basic definitions in each chapter.
Still, the authors barely mention patterns, and in spite of the subtitle of the book, they emphasize process over product. They have developed an elaborate notation for their process, which overwhelms other aspects of the book. This notation is very meticulous, with special numbering for small steps and for every decision. It is an accountant's delight, but I doubt it will please technical people. The simultaneous use of OMT, Booch, and UML is a bad idea, because these methodologies are semantically quite similar and nothing is gained by showing a step of the modeling in three ways. If you understand any of these models, translating your model to another notation is quite simple. State diagrams are treated superficially, a serious flaw since most real systems include complex state diagrams. Instead, they rely heavily on sequence diagrams, which although useful, do not show the complete picture. The only language considered is C++, others are not even mentioned, which gives the misleading impression that you have to use C++ to build object-oriented systems.
Their discussion of architectural aspects is fairly detailed -- probably the best treatment in this group of books. Another positive aspect of Use Cases Combined with Booch/OMT/UML is that it is the only book examined here that uses association classes in its examples. Also, more than one third of the book is dedicated to showing a complete system, including testing. The exercises are realistic, the approach is systematic (too much for my taste). The running example is interesting. While the discussion of testing is too sketchy and has no references, it is a good point of the book to emphasize this important aspect, usually neglected in textbooks.
On the other hand, the style is choppy and the language simplistic. In addition, a number of nonstandard acronyms makes reading this book harder than necessary. On top of this, the authors, rename all standard diagrams, thus "statecharts" become "state transition diagrams (STDs)," "sequence diagrams" become "Process Interaction Diagrams (PIDs)," and so on. It is strange they did not follow UML terminology.
Use Cases Combined with Booch/OMT/ UML is clearly an advanced book, and not appropriate for beginners. It is also the only one in this group that emphasizes process aspects.
Comparing Applying UML and Patterns and UML and C++ raises some interesting points about their respective approaches. Larman doesn't believe in sequence diagrams and uses only collaboration diagrams, while with Lee and Tepfenhart, it is the reverse. Larman barely mentions CRC cards, featured prominently by Lee. The examples in Larman are implemented in Java, while Lee uses C++. Lee and Tepfenhart give more importance to state models but use plain state diagrams instead of statecharts. Larman's book emphasizes Use Cases more.
While none of these books are truly outstanding, UML and C++ could make a good introductory textbook because it provides a restricted but solid and correct foundation. Although it lacks some important details, these can be added by a competent instructor. In fact, I always add numerous case studies from my experience, so this is not a serious flaw. Consequently, I intend to give it a try in an upcoming class. I consider UML and C++ ideal for a short course, where students don't have time to digest more advanced concepts. Larman could be a good alternative for a longer course. Fowler is only useful if you want to get a crash course on UML terminology but don't expect any help in learning concepts. Texel and Williams share some valuable points based on their experience, but its level is too advanced for a first course.
DDJ