Allen is a programmer, educator, and OO design consultant. He can be reached at http://www.holub.com or allen@holub.com.
This column is about software engineering, about how to make high-quality programs using the best tools at hand. I'll be looking at design techniques and patterns, programming-styles, and language issues. You'll find a lot of code in the coming months, but the code will be here to illustrate certain design techniques, not as an end in itself. I'll also share the occasional book and product review when I find something relevant to the design process. Initially, my focus will be on object-oriented (OO) design and C++, but that could change. I'm starting with OO and C++ because these are the most commonly used tools today, and because they are the tools that I use in my daily work.
Since this is a new column, I should probably introduce myself. Some of you will know me from "The C Chest," a column I wrote for Dr. Dobb's Journal from 1983 to 1987. My focus then was on practical programming, good design, and good style in C, and I intend to continue that focus here, but without limiting the discussion to a single language.
I've been working in the computer field since 1979 and as an independent consultant since 1983. I've written all sorts of programs during this time: robot controllers, small operating systems, compilers, lots of UNIX and Windows applications--you name it. Lately, I've been using OO design techniques and C++ almost exclusively. I've also been teaching a lot, both though the University of California, Berkeley Extension, and in-house classes for private companies. Most of this work has focused on object-oriented design and C++ (which I strongly believe have to be approached together), primarily in the Microsoft NT and Windows 95 environments. I've worked a lot with the Microsoft Foundation Classes (MFC)--which will provide us with a rich set of examples of bad design practices in future columns-- and often teach MFC-related topics as well.
In addition to "C Chest," I've written for various computer magazines, am the "MFC Pro" for inquiry.com (http:// www.inquiry.com), and author of numerous books, including Enough Rope to Shoot Yourself in the Foot (McGraw Hill, 1995), about programming styles in C and C++.
I'm going to kick off the column, not with a discussion of a design process or technique, but by discussing the problem of moving to a new design--in this case OO--environment. Since this is a "games" issue, I'll examine how a particular game can be used as a valuable tool in the adoption of OO.
First, some background: Whether a company can successfully adopt OOD as its software-development methodology depends largely on the commitment of high-level management, and "commitment" is the operative word here. ("In a bacon-and-eggs breakfast, the chicken is involved, the pig is committed.") OOD has some very real pluses: You really do get better maintenance, code really does go together faster and painlessly, and once you have a library of reusable objects, programs really are smaller and easier to write. This translates to a real-world competitive edge. To get this benefit, you have to be using the methodology, however, and using OO is a lot like being pregnant--you are or aren't, there's no middle ground.
The main downside is that switching to OO can be a gut-wrenching process. It's not surprising that the internal structure of a company reflects its software-design methodology. For example, if your company follows a traditional "waterfall" model, you'll probably have sales, design, engineering, quality-assurance, documentation, and customer-relations or consulting departments. The program will move from one department to the next (probably in that order) as it's developed. As you'll see in future columns, the OO design process does not follow the "waterfall" model at all. Consequently, any company that adopts OO must change its internal structure to adapt to the new methodology.
My point is that adopting OO can initially be both disruptive and painful, and without serious commitment on the part of the upper management, it won't happen: The company probably will try to take some middle ground that doesn't involve stepping on too many toes, and that way lies madness.
So how do you make the changeover succeed? How do you get the commitment needed to make the change work? The answer is education. Of course, the engineers and designers must be properly trained or they won't be able to do the work. Usually this means a formal training programming--OO is easy to do once the ideas "click," but for some reason it's difficult to learn the ideas from books. You have to learn either from trial and error (which is time consuming and expensive) or by some sort of guided learning process.
Education at the managerial level is even more important. No matter how good the programmers are, OO won't work unless the programmers are provided with an environment in which they're happy. (Most good programmers define "happy" as being able to do the best job possible with the least amount of interference.) The only way to accomplish this is for the managers to really understand what the programmers need, which means that they must thoroughly understand the design process. But how can they do this if they're not programmers (or if the last program they wrote was a Fortran 77 accounting package)? There are books, of course (I'll discuss two at the end of this column), but there's no substitute for experience.
This brings me back to games. Playing computer games is one of the best ways for novices to learn how to use computers. By the same token, games that model the OO design process and, ideally, the behavior of the resulting program, would be a great way to learn about OO.
To choose such a game, you first have to identify the key concepts in OO design. Fortunately, there is more commonality between the various methodologies than differences. All OO design methodologies are concerned primarily with the management of complexity. Rather than pretend that a program can be analyzed mathematically and its correctness proved, the OO designer starts with the assumption that a large computer program cannot be analyzed. To use a big word, large computer programs are nondeterministic: You can't predict their behavior for all possible inputs. An OO designer doesn't try to eliminate complexity, but rather, tries to manage it. The basic tool is a rather extreme form of data abstraction. An "object" knows nothing about how most other objects in the system actually do what they do. An object does know that other objects around it have certain capabilities--a string knows how to print itself, for example, and the object knows how to ask its neighbors to exercise those capabilities--by sending the string a print_yourself() message in the current case.
The system I've described, where one "cell" knows only about the surrounding cells and doesn't have a "big picture," is called a "cellular automaton." These automata are usually quite simple to implement, and can model quite complex natural processes (like the behavior of air when penetrated by an object of a particular shape, say, an airfoil) quite accurately. The cellular automaton with which most programmers are familiar is the game of life. Look at each "cell" as representing a city block. If the population of the surrounding blocks is too high, the cell dies from overcrowding; if the population is too low, the cell dies from loneliness. Otherwise the cell is happy as a clam. Life is easy to implement, and fascinating to watch. A cellular automaton is also a nice application for OO technology since the idea of a "cell" and an "object" are more-or-less equivalent.
Since most real-world objects have much more complex interfaces than most cells, life is a bit simplistic for our purposes. There's a great game that takes the principles of cellular automata in general (and life in particular) to a complex-enough level to be useful for learning about OO at a gut level, and that's Maxis Software's Sim City. If you haven't played it, Sim City is a dynamic model of a city. You are in charge of creating the physical landscape, zoning, and managing the city's infrastructure (building roads, power plants, water mains, and the like). You also set tax rates, establish budgets, and so forth. You are constrained by a budget, and you get your money from taxes.
The city is occupied by virtual inhabitants called "sims" who choose to build (or not), and move into (or out of) your town based entirely on how well the infrastructure supports them and how pleasant a place your town is. The goal of the game is to increase population. If you do things wrong, the city decays and everyone moves out.
So what does all this have to do with OO? First of all, setting up the infrastructure is actually a form of programming. The basic object (a city block) has attributes that you have to define (residential, commercial, and so on) and will interact with adjacent objects based on those attributes. The city is typically modularized into neighborhoods based on the zoning, and the interaction between modules is determined by the transportation infrastructure. The city as a whole (and the day-to-day movement of people within the city) nicely parallels the run-time behavior of an OO program.
One of the first lessons you learn is maintenance. If the budget is too low, roads become impassable, the electrical grid breaks down, and the city stops working. Not the entire city at first, but only parts of it. If you don't solve problems as they arise, the entire city collapses. There are a lot of obvious parallels with computer programs, not only in terms of actually maintaining programs, but also setting priorities and learning to identify the complex interactions between seemingly unconnected parts of a program. This is one of the most difficult lessons for many managers to learn. Changing a seemingly insignificant part of a program can cause unpredictable major problems in other far-away locations. The actual cost of making a change is not just the time spent doing the changing, but also the time spent fixing the resulting problems.
The next lesson is planning. The first few times you play the game, you tend not to design the city, but rather let it grow in an ad hoc way. The city works fine for a while, A road occasionally fails and you fix it. Eventually, you spend all your time responding to crises, however, and growth stops. Every tax dollar that comes in has to be spent just to keep the city viable. Moreover, the situation is quite unstable. If you make even one mistake in deciding what to fix at a given moment, the entire city collapses. Again, the parallel to most large computer programs is obvious. Once you start planning, these problems don't arise. The lessons of city planning apply directly to OO programs. The only way to build a successful large city, in fact, is to design the future city before building anything. You must design the infrastructure to be extensible and learn to modularize your city in such a way that problems in one location do not ripple to other locations. All these are characteristics of good program design in general and OO design in particular.
Obviously, just playing games is not in itself sufficient preparation for the move to OO, but it's a good start. I can recommend two books that are relevant to OO adoption at the managerial level. David Taylor's Object Oriented Technology: A Manager's Guide (Addison-Wesley, 1981) is a concise introduction to OO concepts. Written for nontechnical managers, this book is light reading for most hard-core techies, but it's a good, quick introduction to OO concepts.
A much meatier (and more valuable) book is Adele Goldberg and Kenneth Rubin's Succeeding with Objects: Decision Frameworks for Project Management (Addison-Wesley, 1995). Goldberg is one of the original developers of Smalltalk, and probably has more experience with OO development than anyone alive. This book is not about the OO design process, but rather the process of adopting OO design. It's full of good advice that comes from practical experience; I consider it essential reading for any manager who is considering the move to object orientation.
With respect to this column, a great "intelligent layman's" introduction to cellular automata is Ivars Peterson's The Mathematical Tourist: Snapshots of Modern Mathematics (W.H. Freeman and Co., 1988). A similarly wonderful discussion of life is William's Poundstone's The Recursive Universe: Cosmic Complexity and the Limits of Scientific Knowledge (William Morrow & Co., 1985).