![]() |
|
Lucy Garnett had a great idea. Write a book about C++ aimed at both beginning and experienced programmers. Get them thinking in object-speak first and burden them later with the nitty-gritty of C++ syntax. Add just a touch of business flavor and you have Building Business Applications Using C++: An Introduction to the Object Model. Unfortunately, the great idea is eclipsed by lackluster execution. But at least the concept is sound.
Garnett says in the preface that for the past several years she's been using draft versions of the book to teach a one-year introductory programming course. Billed as a "holistic approach" to object-oriented programming, she's arranged the material in a manner that concentrates first on objects and their interface, spooning out just enough object vocabulary and C++ syntax to reinforce critical points. Later, after thoroughly indoctrinating students in the object-oriented vernacular, the concept of object factories, and the preferred method of setting up files to better handle large, evolving projects, she starts to drub in C++ syntax from array to z. She emphasizes student teamwork, and it's here that Garnett's writing conveys a genuine concern for her students; she wants them to get started on the right programming foot.
As indicated by the book's title Garnet attempts to package three primary themes in one text: object-oriented programming and methodology, C++ syntax and semantics, and the development of "industrial strength" business applications. She manages the first two quite well, but because she's catering to students taking an entry-level programming course, she tends to devote space to topics aimed primarily at entry-level students. As a result, the industrial-strength business applications never really grow beyond mere business-flavored examples.
Going back to pedagogics for a moment, I can see how the material in the book could be translated into a two semester course. Devote the first semester to object-oriented methodologies and C++ issues, leaving to the second semester the development of programming team concepts and advanced C++ idioms. But Garnett fails to dichotomize the text along these lines.
I can live with an unfocused thesis and a perceived deviation from my own pedagogic philosophy. But what I find hard to believe is how sixty-three errors crept between the covers of an otherwise fine text book. Although the adage says you shouldn't judge a book by its cover, it's hard not to in this case -- the first mistake you encounter stares ominously up at you from the back flap. Consider the following snippet: "In Building Bsiness Applications Using C++:..." Was this a harbinger of things to come?
In the interest of objectivity I refused to let one typo sully my opinion before reading at least a few chapters. However, it didn't take long to discover that the unfortunate blunder on the back wasn't simply an editing anomaly in as much as it was the natural order of things. I didn't have to look past the table of contents to find two more mistakes.
Interestingly enough, the more errors I found in the text, the more I wanted to read. It was like playing a game and to keep score I created an error matrix where I recorded page, paragraph, and line number along with the nature of the error and my recommendation for a fix.
Finding sixty-three errors left me with one nagging question: How could the twelve people whom the author acknowledged for their "suggestions, corrections, and comments" fail her so badly?
The physical execution of the book is so bad that it completely overshadows any positive qualities the text possesses. Headers are missing, typos abound, and the diagrams, well, some of them are bungled pretty badly. There are simple errors, propagating errors, errors in logic, errors in presentation and outright blunders. Roughly eight percent of the pages have one or more errors on them. But aside from its many errors, I take issue with several other key aspects of its design.
For one, long source code examples are hard to read because of the poor use of commenting and spacing. Part of the problem is that the size of the font used to represent source code is too big. So, in an effort to squeeze as much code on one page as possible, there are rarely any spaces between the end of one function definition, a comment, and the start of another function definition. This makes following the source code a chore. Mistakes that would otherwise be easy to spot lay buried in scrunched-up code.
Garnett also favors the use of unconventional terminology. For instance, when first introducing the scope resolution operator she refers to it simply as the double colons "::". Later, when she formally introduces the scope resolution operator she calls it the class scope operator. Thinking I had missed something I peeked inside Ellis and Stroustrup's Annotated C++ Reference Manual and couldn't find class scope operator anywhere. Did the ANSI committee rename it? Perhaps the numerous errors in the text can best be explained by this passage from Chapter 11, page 486:
"Bugs almost inevitably creep into complicated algorithms. One of the attractive features of object-oriented programming is that code is written in the expectation of being used over and over in solving many different problems. Reuse helps reveal bugs in the code. Upon detection of an error, a class method can be rewritten without necessitating changes to existing consumer code that already uses objects from that class, as long as the public interface stays the same. The longer a class has been around, the more confidence we, as consumers, have in it."
I see what she's trying to say, and perhaps it's unfair to twist the preceding paragraph into the author's editing cycle manifesto, but too much bad software has been written, and is still being written, with this attitude. It appears as though the author released this book to the public with the same philosophy at heart.
In today's world of black-box programming, the objective should be to make your classes bulletproof. The software engineering profession is already under close scrutiny because of slipshod design and poor programming practices. The author's philosophy of develop while you design and let the bugs work themselves out is amateurish at best and flies in the face of professional programming ethics.
In spite of all of the above, you can still find an occasional highlight here and there. I thought Garnett did a great job with the following topics:
You would think from reading the above list that the book would be ideally suited for beginners but it's not, simply because the errors really confuse the presentation. It wouldn't be so bad if the problems were confined to the text, but some of the worst mistakes are made in crucial diagrams where she's trying to make an important point. I found myself spending lots of time trying to figure out just what it was she was trying to illustrate.
In essence, the author loses face with readers because after the nth mistake, you begin to question the author's sincerity, regardless of the merit of the idea that played the muse.
In its current edition, I can only recommend the author and publisher read it again and fix the mistakes. Novice programmers will get little from the text besides a big headache and a lot of grief. Experienced programmers will put it down despite its shining moments. They can do better with other texts on the market. (Some by the same publisher.) Potential authors will perhaps get the most from the book by using it as an example of what readers don't want to see in a text book. If the author and publisher fix the errors and focus the presentation it would be worth its price. Until then, don't waste your time or your money on it.
-- Rick Miller (millerrw@acm.org)
Part I: Objects, Their Role is Solving Problems, and Their Implementation in C++
1. The Object Model
1.1 Techniques to Manage Complexity
1.2 Objects
1.3 Classes
1.4 Factories and Consumers
1.5 Class Relationships
1.6 Using the Object Vocabulary
Chapter Summary
2. The Problem-Solving Process
2.1 Using the Object Model to Solve Problems
2.2 Outline of a Nine-Step Problem Solving Process
2.3 Case Study: Applying the Problem-Solving Process to a Bank Management
2.4 Directory Schemes Used by Microsoft and Borland (Optional)
2.5 Working in Teams
Chapter Summary
3. The Class Interface
3.1 Programming a Computer
3.2 Organization of a C++ Program
3.3 Interface Code
3.4 Consumer Code
3.5 Factory Code
3.6 Compiling, Linking, and Executing the Logo Framework
3.7 Table of Correspondence Between C++ and Object Terminology
Chapter Summary
4. The Class Methods
4.1 The Method as a Consumer of Other Objects
4.2 Factory Code
4.3 Preexisting Classes That We Can Use
4.4 Using Collaborator Classes
4.5 The Account Class
4.6 BMS Case Study: The CreditCard and Mortgage Class Chapter Summary
5. Control Structures and Method Design
5.1 Overview
5.2 Control Structures
5.3 Top-Down Algorithm Design
5.4 BMS Case Study: A Certificate of Deposit Class
5.5 Guidelines for Algorithm Design
Chapter Summary
Part II: The C++ Language from Ground Up
6. A Bottom-Up Approach to the C++ Language
6.1 A Family Finance Case Study
6.2 Tokens
6.3 Operators
6.4 Expressions
6.5 C++ Statements
Chapter Summary
7. Conditions and Control Statements
7.1 Conditions
7.2 Decision Structures
7.3 Iterative Structures
7.4 Unconditional Branching Statements
7.5 Some Common Algorithms
7.6 A Money Class
Chapter Summary
8. Identifier Syntax
8.1 Basic Identifier Concepts
8.2 Function and Member Function Identifiers 8.3 Data Member Identifiers
8.4 Object Identifiers
8.5 Static Identifiers
8.6 Dynamic Objects
8.7 Class Identifiers
8.8 More Examples
8.9 Common Questions in Coding Definitions and Declarations
Chapter Summary
9. The Backbone of a Well-Designed Class
9.1 The DebitCard Class
9.2 The Destructor, Copy Constructor, and Assignment Methods
9.3 What Constructors Should a Class Have?
9.4 Type Casting from One Type of Object to Another
9.5 Operator Overloading
9.6 Compiler-Supplied Default Behavior
9.7 Summary of a Class's Backbone
9.8 The AccountFile Class
9.9 Inside the AccountFile Factory (Optional)
Chapter Summary
Part III: Implementing Class Relationships
10. Object Composition and the "Has a" Relationship
10.1 Design Considerations
10.2 Using Pointers to Relate Objects
10.3 Pointer Types
10.4 Reference types
10.5 Case Study: A Portfolio Class
10.6 Dynamic Memory Management
10.7 Portfolio Methods Using the new and delete Operators
10.8 Three Different Ways to Return an Object
10.9 RAM and the Memory Manager
10.10 Case Study: A Client Class
10.11 Interfaces for the CertificateOfDeposit, Tbond, and MunicipalBond Classes
Chapter Summary
11. Container Classes and Lists
11.1 Design Issues
11.2 Arrays
11.3 Lists
11.4 Array Implementation of ClientList
11.5 Linked Implementation of ClientList
11.6 Case Study: A Statistics Class
Chapter Summary
12. Templates
12.1 Using the List Template
12.2 The List Interface
12.3 Linked Implementation of the List Template
12.4 More Things You Can Do with Templates
12.5 Compilation and Linkage with Templates
12.6 Putting Together a Project Using a Template
12.7 Using Borland's Container Library
12.8 A Peek at the Standard Template Library
Chapter Summary
13. Class Inheritance and the "Is a" Relationship
13.1 Polymorphism and Inheritance
13.2 Account Hierarchy Interfaces
13.3 Additions to Account Hierarchy Interfaces
13.4 How to Use an Object if You Are Not Sure to Which Class It Belongs
13.5 Account Methods
13.6 Multiple Inheritance
13.7 Private Inheritance
13.8 Some More Examples of Public Inheritance
13.9 Some Rules Governing Inheritance
Chapter Summary
14. IOSTREAM
14.1 Input and Output
14.2 The iostream Class Hierarchy
14.3 Disk File Classes
14.4 The BankStatement Class
14.5 The ClientStore Class
14.6 Variations on the ClientStore Class
Chapter Summary
15. Friends, Constants, and Wrappers
15.1 What Is a Friend
15.2 Constants
15.3 Strings
15.4 Wrapping
15.5 The Date Class
Chapter Summary
16. Error Handling
16.1 Dealing with Errors
16.2 The Problem
16.3 An Object-Oriented Solution
Chapter Summary
Appendix A: Glossaries
Appendix B: Team Project: A Bank Management System
Appendix C: The ASCII Character Set
Appendix D: Table of Operator Precedence
Appendix E: Source Files
Appendix F: Style Manual
| Readability |
|
| Originality |
|
| Organization |
|
| Accuracy | |
| Consistency | |
| Depth |
|
| Timeliness |
|
| Editing | |
| Design |
|
| Overall Value |
|
Explanation of ERCB rating scale: No stars = unacceptable, 1 Star = marginal, 2 Stars = average, 3 Stars = above average, 4 Stars = exceptional.