Farewell to 'Design Techniques'
by Bill Venners
March 15, 1999

First published in JavaWorld, March 1999
This final installment of Design Techniques gives a brief history of the column, tracing its development and maturation, a topical index of the column's back issues, links to related discussion forum topics, and a hint of what's to come.

After 14 months of writing the Design Techniques column, the time has come for me to bring the column to a close. I'm saying farewell -- for a while.

In this final installment of Design Techniques, I discuss what I aimed to accomplish with this column and with my upcoming book based on this material, Flexible Java. I discuss the software development process, software quality, and what role the guidelines and idioms presented in this column can play in helping achieve quality. I give links to all of the previous articles that made up this column, as well as to related discussion-forum topics. Finally, I look ahead to the future.

How 'Design Techniques' got started
In the fall of 1997, having finished my book Inside the Java Virtual Machine, I brought my first JavaWorld column -- Under the Hood -- to a close. I had spent a year and a half immersed in the Java virtual machine, and wanted to turn my attention to a new writing project. For my new project, I decided to combine what I knew about Java with what I knew about good software development practices in general. I wanted to try and capture whatever it is that makes software "good" from the programmer's perspective, apply it to Java, and put it all down in a book.

Although my goal was to help programmers be successful in their Java-based software projects, I didn't want to try and invent a methodology -- a complete theory of how best to manage a software project. Methodologies are difficult to define, in my opinion, because the "best" way to manage a project depends so much on the particular project and the people involved in it. It is hard to generalize, to define a methodology that is universally useful. Sometimes, if you are working by yourself and the project is small, a quick hack is the best way to go. You start coding and can effectively design as you code. The more people who become involved in the project, however, the more important it is to have a formal methodology or process to follow. Nevertheless, I had no interest in attempting to add another methodology to the many that already existed. I wanted to aim my writing project at a smaller target.

My area of interest, and my area of expertise, was writing "good" code and developing "good" designs. I wanted to write a Java book somewhat akin to Kent Beck's Smalltalk Best Practice Patterns and Scott Meyer's Effective C++ -- in other words, a book of guidelines and idioms that could help programmers to make "good" Java-based software.

In addition, I wanted to write a bit about what "good" means in the context of software. Programmers generally can recognize good code or a good design when they see it, but what quality or qualities must a piece of code or a design have to be "good"? I hoped to address this question in my writing project as well.

The Design Techniques column arose from my desire to get the material out in the light of day so that I could get feedback from the Java community as I wrote. Feedback was important to me because I felt that programming guidelines, rather than being chipped into stone by some so-called guru working alone on a mountaintop, should fall out of a discussion among the people who actually have to work with one another's code. Through the Design Techniques column, I wanted to lead a discussion about Java design; to facilitate the discussion, I created a discussion forum on my Web site. (See the section Flexible Java Forum for links to all the discussion forum topics.)

Although a few relevant topics remain that I haven't yet covered in the Design Techniques column, the time has come for me to turn my attention to actually writing the book, Flexible Java. I'll be publishing the text of the book-in-progress on my Web site, artima.com, so you can follow along as I go. I'll also keep the discussion forum open, and I encourage any feedback you may have to offer. If you want to receive periodic updates of my progress, you can join my mailing list. (See Resources for links to all of these things.)

Software development as 'conversation'
I was recently a guest at an object-oriented design seminar taught by Bruce Eckel and Larry O'Brien. At one point in their seminar, Bruce and Larry gave the attendees a two-page "statement of work" for a software project. The attendees separated into groups of four or five, and each group began discussing how it would design software to meet the requirements set out in the statement of work. I roamed from group to group, listening and participating in the discussions. While each group had its own personality, the groups had much in common. In particular, I saw in all the groups the same basic process in action, a process I'd seen over and over in real software projects on which I'd worked. I like to call this process "the conversation."

I see the software development process as a conversation because throughout the entire process people must communicate with one another, and the effectiveness of that communication is critical to the success of the project. In the beginning of a project, for example, some person or group must decide on and communicate the requirements of the project. These requirements may come in many forms, from an offhand verbal comment in the hallway to a series of meetings that results in a formal written document. Regardless, a target must be defined and in some way presented to the programmers who will be drawing the bow and firing the arrow. This is the first aspect of the conversation.

Once (the initial version of) the requirements has been defined and communicated, developers must get together at some point and discuss how to build a system that meets those requirements. It is this part of the conversation that I was observing at Bruce and Larry's workshop: a group of developers sitting around a table, brainstorming, naming things, drawing diagrams, debating, laughing, arguing, insisting, compromising, deciding. This fleshing out of a design given the requirements is yet another aspect of the conversation. Not only must the group decide on a design via group interaction, it must also in some way communicate the design to others who will help write the code.

Somewhere along the way, of course, code must get written, and even this activity is part of the conversation. The code is part of the conversation because developers on the same team must often, by looking at the code, understand what the other developers have done. Any changes made must then be understood by developers who come to the code later. So when you write code you aren't just communicating with the computer (telling it what to do), you are also communicating with any other programmers who may ever look at your code.

There are many other aspects of the conversation. The people who test the software must understand what it is they are testing. Managers must communicate with developers, developers with managers, developers with other developers, managers with other managers, and so on. Throughout the lifetime of the project, small and large corrections in direction must be communicated. Priorities shift. Requirements change. Unforeseen problems are uncovered along the way. All these things must be effectively communicated as the process continues.

Where 'Flexible Java' fits in
So what part of this vast conversation did I hope to address in my writing? Put simply, I wanted to focus on the code.

How rare it is that maintaining someone else's code is akin to entering a beautifully designed building, which you admire as you walk around and plan how to add a wing or do some redecorating. More often, maintaining someone else's code is like being thrown headlong into a big pile of slimy, smelly garbage. You have to find some way to rearrange the garbage to fix a bug or make an enhancement. You regularly make appalling discoveries that grate against your design sensibilities. Now I don't like swimming around in garbage, and (I would hope) you don't either. Thus, my ambitious goal for my writing was to try and help reduce the amount of "garbage code" in the world -- to write a book that could help programmers produce better designs and code.

But what does 'good' mean?
The trouble is, what makes one design or piece of code "better" than another? What makes a design good? What makes code good? To address these fundamental questions, I'd first like to quote a few paragraphs from my first Design Techniques article, in a section called "Software development monkeys on your back":

In the real world, as you work to design and implement software, you have several concerns to keep in mind -- several "monkeys on your back." Each monkey competes with the others for your attention, trying to convince you to take its particular concern to heart as you work. One large, heavy monkey hangs on your back with its arms around your neck and repeatedly yells, "You must meet the schedule!" Another monkey, this one perched on top of your head (as there is no more room on your back), beats its chest and cries, "You must accurately implement the specification!" Still another monkey jumps up and down on top of your monitor yelling, "Robustness, robustness, robustness!" Another keeps trying to scramble up your leg crying, "Don't forget about performance!" And every now and then, a small monkey peeks timidly at you from beneath the keyboard. When this happens, the other monkeys become silent. The little monkey slowly emerges from under the keyboard, stands up, looks you in the eye, and says, "You must make the code flexible -- easy to read and easy to change." With this, all the other monkeys scream and jump onto the little monkey, forcing it back under the keyboard. With the little monkey out of sight, the other monkeys return to their customary positions and resume their customary activities.

As you sit there in your cubicle and work on your software, which monkey should you listen to? Alas, in most cases you must listen to all of them. To do a "good job," you will need to find a way to keep all these monkeys happy -- to strike a proper balance between these often conflicting concerns.

Basically, my opinion is that good designs and code strike a balance between flexibility, performance, and other concerns, but lean heavily toward flexibility. I believe that flexibility should be sacrificed in the name of performance only in rare, appropriate cases. Therefore, the guidelines and idioms I presented in the Design Techniques column were aimed primarily at helping achieve flexibility in Java code and designs. The upcoming book, Flexible Java, will have the same focus.

Why flexibility?
Why do I feel that flexibility is generally the most important quality you can give to your designs and code? The reason is that, as one of my managers used to put it, "software is a living product." Code isn't static. It is constantly being tweaked, enhanced, fixed, and so on, by a team of programmers, a team that is usually in constant flux itself.

The code is like a magical text that is constantly expanding and contracting, changing shape on the behest of a group of elite high priests and priestesses who know how to care for the thing. Flexibility is important precisely because the code must constantly be changed, day to day, month to month, year to year. The more flexible the code is -- that is, the easier it is to understand and change -- the more smoothly and efficiently this fundamental activity of software development can take place.

So, flexibility is the prime focus of the guidelines and idioms I presented in the Design Techniques column. I hope the articles in this column have helped the software development conversation in many corners of the world, and that they continue to do so in the future. As always, the previous issues of JavaWorld will remain online, so you should always be able to get to Design Techniques material.

Index of 'Design Techniques' articles
Here is an annotated list (in chronological order) of all the articles published in the Design Techniques series:

  • Introduction to 'Design Techniques' (February 1998) -- The first installment of the Design Techniques column introduces the column and discusses the larger issues involved in designing Java programs. In addition, it examines the software development process in general, describes the role of design within that process, and looks at the various and competing goals of a "good" software design. (4,500 words)
  • Object initialization in Java (March 1998) -- This article describes in detail the process of object initialization in Java programs. It discusses constructors, initializers, instance initialization (<init>) methods, initialization and inheritance, object images on the heap, and the order in which an object's variables get initialized. It serves as a companion to the regular Design Techniques installment, "Designing object Initialization." (5,000 words)
  • Designing object initialization (March 1998) -- This installment of Design Techniques begins with a quick look at object design fundamentals, then goes on to discuss various approaches to designing initializers and constructors so as to facilitate the proper initialization of objects. (4,000 words)
  • Designing fields and methods (April 1998) -- This article shows how some fundamental software design techniques, such as avoiding special data values and minimizing method coupling, apply to Java. (4,000 words)
  • What's a method to do? (May 1998) -- This article shows how to maximize method cohesion while avoiding method explosion. (3,500 words)
  • Object finalization and cleanup (June 1998) -- This article discusses design guidelines that pertain to the end of an object's life. (3,500 words)
  • Exceptions in Java (July 1998) -- This article gives an in-depth account of exceptions in the Java language and virtual machine. (6,000 words)
  • Designing with exceptions (July 1998) -- This article discusses design guidelines concerning when and how to use exceptions. (3,000 words)
  • Designing for thread safety (August 1998) -- This article discusses design guidelines concerning when and how to make objects thread-safe. (3,000 words)
  • The event generator idiom (September 1998) -- This article discusses how and when to make a Java class observable. (3,000 words)
  • The canonical object idiom (October 1998) -- This article proposes an idiom that defines a baseline set of functionality for objects. (2,500 words)
  • Inheritance versus composition (November 1998) -- This article discusses how to choose between inheritance and composition. (2,500 words)
  • Designing with interfaces (December 1998) -- This article discusses how to use Java's interface. (2,500 words)
  • Designing with dynamic extension (January 1999) -- This article discusses how to use forName() and class loaders in designs. (2,500 words)
  • Designing with runtime class information (February 1999) -- This article discusses how to use all the information about an object's class that is available at runtime. (3,500 words)
  • Designing with static members (March 1999) -- This article discusses how to use static fields and methods. (1,500 words)

The Flexible Java Forum
Here is an annotated list of discussion topics at the Flexible Java Forum:

A thank-you
Before I go, I'd like to say thanks to all the readers of my Design Techniques articles. I hope you found them useful.

Thanks especially to those who submitted feedback, either through e-mail, through the comment boxes at the bottom of each JavaWorld article, or via the Flexible Java Forum. The feedback, especially criticism, was very helpful.

What's next
From this point forward, my design-oriented writing will be focused on writing Flexible Java. I will be publishing the book-in-progress on my Web site as I write it, so you can follow along and, if you wish, send me feedback. If you would like to receive occasional announcements as I progress through the writing of the book, you can sign up for my mailing list.

As far as JavaWorld goes, another column is in the planning stages. In the next few months, I should return with a monthly column focused on distributed systems programming in Java, RMI, and Jini.


This article was first published under the name Farewell to 'Design Techniques' in JavaWorld, a division of Web Publishing, Inc., March 1999.

Talk back!

Have an opinion? Be the first to post a comment about this article.

About the author

Bill Venners has been writing software professionally for 12 years. Based in Silicon Valley, he provides software consulting and training services under the name Artima Software Company. Over the years he has developed software for the consumer electronics, education, semiconductor, and life insurance industries. He has programmed in many languages on many platforms: assembly language on various microprocessors, C on Unix, C++ on Windows, Java on the Web. He is author of the book: Inside the Java Virtual Machine, published by McGraw-Hill.