An OO-Design Reading List

This page lays out a few of my favorite books on OO Design and related topics. This list is far from exhaustive (except for your budget), but it's a good start if you really want to learn the subject in depth. I'll probably tweak it occasionally, and I'm interested in any books that you might know that I could add to this list.

Spreading the Word

The first problem is "Conway's Law:"
The structure of a system tends to mirror the structure of the group producing it.

–Mel Conway (April, 1968 Datamation)

Put another way, if you change the structure of the system, the structure of the group will have to change as well. These changes are probably the biggest impediment to adopting an OO methodology. The Director of QA, for example, will not be pleased when told that his entire test staff will be distributed amongst the engineering teams.

But even when you decide to make the change, you'll find problems. Probably 90% of the programming shops that believe they're doing OO are wrong in their beliefs. A few more quotes are relevant:

There is nothing more difficult to plan, more doubtful of success, nor more dangerous to manage than the creation of a new order of things.... Whenever his enemies have the ability to attack the innovator they do so with the passion of partisans, while the other defend him sluggishly, so that the innovator and his party alike are vulnerable.

–Niccolo Machiavelli (I bet you didn't know that he was a software-development manager)

Ignorance more frequently begets confidence than does knowledge.

–Charles Darwin

A long habit of not thinking a thing wrong, gives it a superficial appearance of being right, and raises at first a formidable outcry in defense of custom.

–Thomas Paine

My experience with writing about OO exactly reflects all these observations. When it comes to OO, many programmers and managers just don't "get" it, and this lack of understanding often translates into the vigorous defense of bad programming technique and vicious attacks on whoever tries to bring real knowledge into the mix.

Here are two resources that will help you both understand what you're up against when you try to present new ideas to people and help you get the ideas across more effectively:

Self-Insight: Roadblocks and Detours on the Path to Knowing Thyself (Essays in Social Psychology)

Justin Kruger and David Dunning's Unskilled and Unaware of It: How Difficulties in Recognizing One's Own Incompetence Lead to Inflated Self-Assessments (Journal of Personality and Social Psychology 77:6 [Dec. 1999], pp. 1121-1134) discusses both why people are unable to recognize their own incompetence and why people defend their incompetence so tenaciously. This paper has rolled off the APA web site, but here's a Scanned Version, and here's a more readable PDF version, but with smaller tables. There's also a write up on Wikipedia. Also of interest is Ehrlinger et al's Why the unskilled are unaware: Further explorations of (absent) self-insight among the incompetent.

In their words:

...consider the ability to write grammatical English. The skills that enable one to construct a grammatical sentence are the same skills necessary to recognize a grammatical sentence, and thus are the same skills necessary to determine if a grammatical mistake has been made. In short, the same knowledge that underlies the ability to produce correct judgment is also the knowledge that underlies the ability to recognize correct judgment. To lack the former is to be deficient in the latter.

This book, Self-Insight: Roadblocks and Detours on the Path to Knowing Thyself, provides a synopsis of this work along with a discussions of related problems, like: why is so hard to come up with an accurate estimate? It's an essential read.

Diffusion of Innovations, 5th Edition

Everett Rogers's, Diffusion of Innovations discusses two essential problems: (1) Why is it that new ways of doing things are not adopted, even though it's obvious to everyone that the new way is better, and (2) how do you go about bringing about that adoption. That is, how does an innovative technique infuse an organization (or not). This is an academic book, but is, nonetheless, an enjoyable read, full of useful insights.

User-Interface Design

UI Design is an integral part of the design process. It helps you determine what the program has to do, some of the structure of the class hierarchy can be inferred from it, and most importantly, it provides you with a way to test your requirements-gathering process.


The Visual Display of Quantitative Information, 2nd edition

Edward Tufte's The Visual Display of Quantitative Information is a spectacular book. It discusses how to present numbers in such a way that their meaning is clear. This clarity is an essential component in a decent UI, particularly in reports and other output. If a user has to pull out a calculator or draw a picture to make sense of the output your program presents, then there's something wrong with your UI. People use your program because they want an answer to a particular question. You should provide them with that answer, not with the wherewithal they need to find the answer. This book shows you how to create output that's actually useful. Tufte's other books Visual Explanations and Envisioning Information are also very good. It's worth owing all three.

Software for Use: A Practical Guide to the Models and Methods of Usage-Centered Design

Larry Constantine and Lucy Lockwood's Software for Use is about the important parts of UI design — things like flow, page organization, usability, and so forth. This is not a book about art; rather it shows you how to create a very usable interfaces, and along the way, design programs that actually do something useful. The result of their process is an "abstract" UI design that shows you what goes on the page and where, and defines the movement between pages. This sort of "abstract" design is ideal for use in the design process. You can give the abstract model to a graphic artist to make it look pretty.

Constantine and Lockwood's approach is based primarily on use-case analysis, which is also a fundamental part of developing your object model. That is, they identify the fundamental tasks that the program has to accomplish, and then design a UI that walks you through those tasks in an efficient way. By basing the UI design on the use cases, you guarantee a coherent integration of the user interface and the object model that makes the program easier to build and maintain as well. The UI is not a veneer on the top of the code, it's a visual representation of the code itself.

You should also check out the authors' web site www.foruse.com, which has lots of links to other UI-related books, etc.

See Also: Alistair Cockburn's Writing Effective use Cases, below.

The Design of Everyday Things

Donald Norman's "Design of Everyday Things" is the classic book on design for usability. It explains how to design, not just software, but things in general, so that their use is easy and intuitive. The principles in this book are universal.

 

 

Alan Cooper is the inventor of Visual Basic. Though I disagree with him about a lot of stuff (e.g. Visual Basic), he's done a lot of great UI-design work. One of his most important ideas is the notion of "goal-directed design," where you consider your user's implicit goals as an integral part of the design process. The idea is expounded in Goal-Directed Software Design from Dr.Dobb's Journal, July 2001 (originally in the Sept., 1996 issue). [Alan's company site]



In addition to the preceding books, several good UI books talk about what works and doesn't work in the UI itself: where to put the buttons and what fonts to use, etc. The problem with this approach is that the books are so focused on the minutiae of the UI that they loose track of the the big picture. Reading a book of this sort is like reading a book on language traps and pitfalls before you learn how to program. Nonetheless, these are great books to go through once you've read something more pithy, such as Software For Use, described above.

The following books are all written by opinionated (and amusing) people who present their opinions as gospel. It helps that I happen to agree with most of what they have to say.

OO-Design Concepts

Object Design: Roles, Responsibilities, and Collaborations

Rebbecca Wirfs-Brock is one of the pioneers of OO Design. Her Object Design: Roles, Responsibilities, and Collaborations covers her most recent thinking on the design process. Wirfs-Brock uses CRC cards as a means of defining objects, and her methodology gets you to focus, correctly, on what an object does rather than what it contains. Most precisely, she emphasizes the notion of defining an object by its set of responsibilities defined in a "class contract," Essential concepts that most people who think they know OO simply because they know an OO language don't understand adequately.

Even if you're using a different methodology, you'll find the insights in this book useful. If you're coming from a procedural background, this book can help shake you out of the fundamentally incorrect object-as-bag-of-data-with-intelligent-warts mindset.

Object-Oriented Design Heuristics

Arthur Riel's Object-Oriented Design Heuristics teaches the difference between a good and a bad OO design. It's approach is to present a set of 60 rules of thumb that, if followed, will lead towards a good design. Reil talks a lot about both class structure and object interaction. The book not only presents the rules, but also talks extensively about what the rule accomplishes—an essential component of a book of this sort. Simply following rules by rote, without an understanding of why the rule exists, will not get you very far.


Other interesting OO-concept books:

UML

UML is just a notation — a graphical way to describe a problem and a software-based solution to that problem. It is not a design process, and it is not a programming language. (A friend of mine says that a UML diagram is full of "useful ambiguity.") Visual modeling is an important part of the design process, however, and knowing UML is an essential prerequisite.


Allen Holub's UML Quick Reference (on this site at http://www.holub.com/goodies/uml) is a concise reference to most of the Unified Modeling Language (UML).
UML Distilled: A Brief Guide to the Standard Object Modeling Language (3rd Edition)

Martin Fowler's UML Distilled, 3rd Edition is a much better presentation of UML than the actual standard document (listed below). It's concise and to the point, but has enough explanation that you understand what the notation actually does.

Also of interest is Miles and Hamilton's Learning UML 2.0 which is less of a reference and more of a textbook, so provides a gentler introduction to UML, than UML Distilled.

Get the UML 2.5 Standard (along with a bunch of other useful stuff) from OMG at http://www.uml.org. The UML Superstructure document is the one that actually describes the notation. This document is, even by the standards of a "standard," very poorly written. It's 600+ page bulk could easily be reduced to about 50 easy-to-read pages. However, It is the official standard, for what that's worth.

Process

I'm not happy with any of the books that talk about the software development process. First, many writers seem to go to extremes with which I disagree (heavy up-front modeling of the entire system vs. no modeling at all, for example). Next, books on process are often dogmatic, and the code in many of the process books I've read is just plain bad. It breaks basic OO principles like implementation hiding, for example. My own processes are a hybrid of (what I think of as) the best practices of various methodologists. For example, there's a lot of spectacularly useful stuff in Extreme Programming (pair programming, test-driven development, constant refactoring, on-site customers, building the program one use-case scenario (i.e. "story") at a time rather than on a class-by-class basis). On the other hand, I'm also a big fan of formal requirements gathering in the sense of customer interviews, written problem statements, formal use-case analysis, and visual (UML) modeling. The process I use has elements of Extreme programming, elements of the so-called "Rational" Unified Process, and techniques that aren't formally part of either of these methodologies.

Your best bet is to read several books and decide what works best for you. None of these books are perfect.

UML Distilled: A Brief Guide to the Standard Object Modeling Language (3rd Edition)

Use-case analysis is an essential part of every OO-Design methodology. Alistair Cockburn's Writing Effective Use Cases is the best book going on how to assemble and work with use cases. It takes a practical approach the the subject that's both refreshing and usable. It's a good complement to Constantine and Lockwood (above).

Balancing Agility and Discipline: A Guide for the Perplexed

Boehm and Turner's Balancing Agility and Discipline is a good discussion of the benefits and problems associated with both Agile and heavyweight development methodologies. They try to come up with a balanced approach that leverages the best characteristics of both approaches.

Extreme Programming Explained: Embrace Change

Kent Beck's Extreme Programming Explained started a revolution in software development. It was the first book anyone had seen on an Agile-development methodology, and was extremely controversial. Extreme Programming (XP) is still controversial, particularly in its insistence that the only real documentation you need is the code itself, and that up-front design should be avoided. Nonetheless, there's a lot of great stuff in this book—practices, the adoption of which would benefit even a hard-core heavyweight-process shop.

I think one of the biggest problems with this book is that Beck assumes that the reader is knowledgeable of good OO technique and structure. Its bibliography lists many books that should actually be prerequisites to this one. (That bibliography, by the way, is exemplary.) Someone who doesn't have these prerequisites could easily jump to the wrong conclusions. For example, Beck assumes that you're doing something like use-case analysis to come up with XP "stories." An inexperienced reader wouldn't know that, however, and might even skip requirements gathering entirely, since Beck doesn't discuss it.

Growing Object-Oriented Software, Guided by Tests

At the center of all the Agile processes is the notion of test-driven design (TDD): writing the tests before you write the code, and running the tests as often as every few minutes. Steve Freeman's Growing Object-Oriented Software, Guided by Tests is maybe the best book on the subject. Not only does he cover how to do TDD, but he explains how to do it in a way that makes your system better from an object-oriented perspective. That is, it's a book that's as much about design as it is about testing. The book also shows you how to do TDD with a full-blown real-world example presented in depth.

Agile Software Development, Principles, Patterns, and Practices

Robert ("Uncle Bob") Martin's Agile Software Development is probably a better introduction to Agile techniques than Kent Beck's book. Martin doesn't gloss over the details as much as Beck, and there are several valuable step-by-step walkthroughs of the development process. There's a lot of great advice in here that's entirely missing from Beck's book.

The Unified Software Development Process

Jacobson, Booch, and Rumbaugh's The Unified Software Development Process describes the best of the formal development methodologies. In a remarkable marketing coup, IBM's Rational Software has managed to get everyone to call the process the "Rational Unified Process" (RUP), but the process has nothing to do with IBM/Rational. I'm not satisfied with any of the RUP-Explained or RUP-Distilled books, so you may as well go to the horse's mouth. The book is a bit dry, but it's thorough.

Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process (2nd Edition)

Craig Larman's Applying UML and Patterns bears the same relationship to the Booch Unified-Process book that Martin's book does to Beck's Extreme-Programming book. That is, it shows you the Unified Process in action, taking you step by step through the evolution of a design, talking about the problems you might encounter along the way.

Refactoring: Improving the Design of Existing Code

Refactoring — the process of improving the quality of code without changing the way the code works — is an essential part of the development process. Martin Fowler's Refactoring: Improving the Design of Existing Code is a valuable catalog of programming "bad smells" and how to fix them. Reading this book will not only show you how to fix problems in the code you wrote before you knew what you were doing, but will help you not make the mistakes in the first place.




Other interesting management-related books are:

Design Patterns

The design patterns fit in at end of the design process. They are concerned primarily with the implementation-level design. Often, the design patterns will be used entirely by the programmers, and won't appear in the formal architecture at all.

In addition to the books listed, below, you should check out http://hillside.net/patterns, which I think of as "Patterns Central" on the web. Here, you'll find many links to books, articles, pattern catalogs, and other useful, design-pattern-related material.


Holub on Patterns: Learning Design Patterns by Looking at Code

My own book, Holub on Patterns: "Unlike the majority of books on design patterns in software, this one is not structured around a series of stand-alone patterns that exist in splendid isolation. Where most patterns books are catalogs of varying degrees of complexity, this one is heavily code-centric and seeks to show patterns as they exist in the wild. This makes for a much more complex and demanding read but it's necessary because the real world is much messier than the relatively simplistic world that emerges from the relatively simple examples in many design patterns texts. There's no doubt that there's a big gap between an intellectual understanding of patterns and being able to recognize when and where to use them in your own code. This is the gap that Allen Holub aims to bridge with this book." (From the review on TechBookReport )

James Edward Gray also reviewed the book on Slashdot.

Design Patterns: Elements of Reusable Object-Oriented Software

Design Patterns, by Gamma, Helms, Johnston, and Vlissides (otherwise known as the "Gang of Four"), is the classic catalog of design patterns that started off the whole movement. It's one of the most important CS books written in the past 20 years. Though the book is academic in its treatment, it's thorough in its coverage. My book, Holub on Patterns, covers the same material, but with a more practical emphasis.

Pattern Languages of Program Design

The Pattern Languages of Program Design books books are the collected proceedings of the periodic "PLoP" conferences, one of the main events in the design-patterns world. Together, they represent a vast repository of patterns not covered in the Gang-of-Four book, in problem areas ranging from threading to client-server systems. All five books are well worth your time. The link at left gets you to the Amazon page for the first volume, but here are links to vol. 1, vol. 2, vol. 3, vol. 4, and vol. 5.

Patterns of Enterprise Application Architecture

Martin Fowler's Patterns of Enterprise Application Architecture focuses on patterns that come up in large Enterprise-level programs (as compared to the other books in this section, which address more general problems that are likely to come up in any program). It's an essential book for anyone who is working on very large systems.

Pattern-Oriented Software Architecture Volume 1: A System of Patterns

Buschmann et al's Pattern Oriented Software Architecture: A System of Patterns is focused more on architecture than on individual patterns. That is, the book concerns itself with how several patterns work together in concert to solve bigger problems than do the individual patterns in isolation. This book is one of the few that describes the the Presentation-Abstraction-Control (PAC) architecture that I've talked about extensively in articles on alternatives to Model-View-Controller.

Volume 2, Patterns for Concurrent and Networked Objects, is also good.

Refactoring to Patterns Martin Fowler's Refactoring, discussed above, is the essential introduction to the refactoring process. Joshua Kerievsky's Refactoring to Patterns focuses on refactoring existing ad-hoc code into code that uses the Gang-of-Four design patterns. That is, once you learn the patterns, you tend to see all the places in your existing code where you could have used them, but didn't. Kerievsky shows you how to fix that less-than-ideal code.

Management

Parkinson's Law

C. Northcote Parkinson's Parkinson's Law states: "Work expands to fill the time available for its completion." This is a funny, and at the same time pointed, discussion of why most organizations aren't able to reign in out-of-control projects.

The Mythical Man-Month: Essays on Software Engineering, Anniversary Edition (2nd Edition)

The Mythical Man-Month is a classic, written by Fred Brooks to summarize the issues that arose when he led the OS/360 project for IBM. This is the book where "Brook's Law" ("adding manpower to a late software project makes it later") comes from, but it holds a lot of other pithy observations as well. The book is every bit as relevant today as it was when it was written in the late 70s. This edition contains the full text of the wonderful "No Silver Bullet" essay, from Computer Magazine (April 1987)

Peopleware: Productive Projects and Teams (Second Edition)

Just about everything that Tom Demarco's written is worth reading. His Peopleware, however, is the quintessential book on software-project management. Everybody should read it. Period.

General Computer Science

Some interesting papers that are worth reading, but aren't particularly related to anything else on this page:

Guy Steele's, Growing a Language (presented at OOPSLA in 1998) is a classic (and wonderfully written) argument for extensibility in computer languages. Steele argues for the use of simple programming languages that can be extended by means of mechanisms like subroutine or class definitions. The main flaw in Steele's argument is that he assumes that the extensions will be elegant and appropriate. My experience is that extensions are often haphazard, and the resulting extended language is too chaotic to be viable. A well designed small language that solves a specific problem is often better than the all-too-typical system of poorly done extensions. Whether or not you agree with him, this article is well worth reading.

Edsger Dijkstra's Programming Considered as a Human Activity (Proceedings IFIP Congress 1965) discusses the notion of "elegance" and how it applies to programming languages and programming. He argues strongly for elegant, as compared to expedient and ugly, solutions to problems.

A. M. Turing's paper Computing Machinery and Intelligence (Mind, 59 [1950], 433-46) discusses whether or not machines can think, and presents what is now called the "Turing test" for whether or not a machine is "intelligent."

Winston Royce is the guy who invented the notion of the "waterfall model" of software development. Here, in the original paper on the subject— Managing the Development of Large Software Systems (from the Proceedings, IEEE WESCON, August, 1970 [pp. 1-9])—he states unambiguously: "[The waterfall model] is risky and invites failure." This bold statement does make me wonder why anyone ever thought it was a good idea to use waterfall development, but there you are. (See Kruger and Dunning, above.)

Conway's Law states that “Any organization which designs a system ... will inevitably produce a design whose structure is a copy of the organization’s communication structure.” This notion is central to explaining the resistance you'll meet when trying to adopt an object-oriented Agile process. Conway presents his notions in the article How Do Committees Invent?, from the April, 1968 Datamation.