A Way of Thinking

Author Peter Arthur Loeb
Email peter@palserv.com
Date August 17, 2001
Last Update August 27, 2001

Contents

Acknowlegements

My thanks to Theodore Sturgeon for the title and all it implies.

The GoF for their wonderful book.

The folks at the Sun Java Center for their J2EE design patterns book.

Back to top

Introduction

About the Author

I have been programming for over 20 years. This includes:

This list is rather incomplete. I truly cannot remember all the languages I have learned, and some, which I remember all too well but would rather forget. Some people would list SQL, HTML, and XML as languages, but in my mind, they are not programming languages, so I don't include them, either.

I have been playing music at a professional level for a very long time. I have always gravitated towards the creative side of music (composition and improvisation) rather than the meticulous re-creation of someone else's composition (orchestra or pit work). This gives me a somewhat different (if not unique) perspective on programming. In music, partly because of a long tradition of artistry, I learned how to cross the line "where craft becomes art". Moreover, I learned to cross this line many times - in composing, arranging, and the playing of a wide assortment of instruments. (These days, I have pretty much restricted my playing to piano, upright bass, drums, and sax). If you want to hear some of my music, check out my web site.

When I began programming, I found that after a few years, I was able to cross the line "where craft becomes art" This was made much easier by the fact that I had crossed this line so many times in music, where there is a tradition of this kind. Programming is way too new. We are creating our own ways, which will become the next generation's traditions. Artistic, creative programming is still quite rare (or at least, medium rare). Some of those who have succeeded in this endeavor have tried to teach how they program. This has led to various paradigms and methodologies.

Back to top

About this Article

There have been many paradigms and methodologies in programming. From Knuth's classic book about algorithms and the methodology of "structured programming" to the more recent object orientation and design patterns, people try to teach (by writing down) what they know. This is a worthy endeavor. But not always a successful one.

I have seen too many programmers who have learned the current ("hot") methodologies and paragigms, who know all the buzz words, but who still can't program to save themselves. I believe that there are several reasons for this.

The enormous sales of "how to" books about programming should give us a clue. People want to learn. The authors of these books tell their readers that they can become great programmers, if only they will follow the "simple" instructions in that particular book. Meanwhile, companies complain that there are not enough good programmers.

I believe that a good programmer will create good programs with any paradigm or methodolgy and a lousy programmer will create lousy programs not matter what they do. Thus the question begins to resolve to: how to make a good programmer out of a lousy one. This has been the aim of all the paradigms and methodologies, but for the most part they haven't worked.

I will try to address some of these issues in order to shed some light on them, while I attack the main idea of this book: that design patterns should be used to develop "a way of thinking". I am NOT trying to teach anybody how to do anything. This article is quite abstract. It is meant to promote thought and discussion on what I think is an important issue.

Back to top

About Specific Books

So far, I have read two books of Design Patterns, the "GoF" book and the "J2EE" book. Although the GoF book is already a "classic" and the J2EE book will probably become one, they are not perfect. Some of things I have to say may sound somewhat negative, but they are not meant that way.

The "GoF" Book

This is the first book I read on Design Patterns. It is now considered to be the classic book on Design Patterns for programming. It deserves this consideration. One indication of this is the number of books which have been published since this book which do little more than try to re-hash these patterns in a specific context. One obvious example is from the same publisher (does that make it all right?), Addison Wesley: "Java(TM) Design Patterns: A Tutorial".

The only thing missing (in my opinion) from their template is a "Solution" section, and in particular, a "capsule" description of the solution. I think this would have made the book just a bit easier to digest.

Part of the reason for this article is that (in my opinion) there is little or no information in this book on how to develop "a way of thinking" about how to use design patterns. The authors seem to believe that if you read their book and struggle through enough code, you will automatically develop this skill. I disagree; thus this article.

Back to top

The "J2EE" Book

This article started out as a response to the "feedback" request for this book on the Sun web site.

The first thing I noticed about their catalog is the inclusion of a "Solution" section in their template. In particular, the first part of the section is in "bold" to set it apart. This gives us a "capsule" description of each pattern; a very nice touch.

What I missed was the lack of coding examples. I realize that this would have made the book much longer, but I believe that some code, even if incomplete, would have made it much easier to understand just what the authors are trying to say.

There is little information on how to use patterns in general or what patterns are. Clearly, this is not the intent of the book, so I don't have a problem with it.

Back to top

The JDK Source

In the Java JDK, there is included a "src.jar" file, which contains the source code for almost all of the packages which make up the "API".

It is clear that the people at Sun read the GoF book very carefully. The Java API is full of fabulous examples of Design Patterns at work. I am just beginning my journey through this maze. Perhaps I will take notes and write an article about it.

Back to top

Paradigms and Methodologies

Long ago and far away (a few years ago in a shop across town) programmers were struggling with getting things done. One fellow named Og (I will call him "Og" with the hope that there isn't really anybody with that name around to get offended. If there is, I apologise now.) seemed to do quite a bit better than everybody else. He didn't put in more hours. He took long breaks. He often looked as if he wasn't working at all (staring off into space, etc.) But he got results.

Og's manager hated Og, but the other members of the "team" loved him. But Og's manager was not stupid. He realized that Og was on to something. He had Og teach the other members of the team what he was doing.

So Og thought long and hard about what he did. He took notes. He wrote lesson plans. He taught a course. A few years (and several managers) later, the course began to bear fruit. The other members of the team showed great improvement.

All involved credited Og. A publisher got wind of this and Og wrote a book, "The Og Method". Word spread. The book sold well. But very few programmers really improved very much as a result of reading the book. Everyone wondered why.

What everyone missed was that the members of the original team worked closely with Og for several years. Not only did Og explain his ideas repeatedly, but as they "hung out" at work, the other team members began to get a glimmering of Og's way of thinking. Particularly, with Og to help them along, they improved.

Paradigms and methodologies are specific ways to do things. I believe that most get their start in a manner similar to the story of Og. The problem is that neither a paradigm or a methodology can truly convey a way of thinking.

Back to top

Design Patterns

Design patterns are a way of capturing ideas and setting them down for others to understand. They began in the field of architecture. It didn't take long for the programming community to pick up on them.

Design patterns are not a methodology. But a methodology can be expressed in design patterns. Aspects of a paradigm can be expressed in design patterns.

The design pattern books I have read are concerned with object oriented programming and design. Within that scope, they are both excellent. Their authors are to be thanked profusely for sharing these ideas. However, these books leave something out. The authors assume that if a programmer could just understand a certain principle, then they would become a better programmer.

Well, it certainly can't hurt a programmer to understand as many principles as possible. Particularly the ones in the design pattern books I've read. However, this is not enough. Merely learning a bunch of design principles will not make one into a good programmer. As long as the authors of the design pattern books restrict themselves to attempting to capture paradigms and methodologies, they will miss the mark.

Back to top

A Way of Thinking

To paraphrase Julian "Cannonball" Adderley, "good programming is a state of mind, not a fact of life." Learning facts is ok, but they need to be organized. There is nothing wrong with methodologies and paradigms, but they don't convey a way of thinking.

It is my intention to try to show how we can develop ways of thinking which may lead to better programming. I will use the GoF design pattern book as a basis for several reasons:

What I have to say should not be taken as a criticism of this seminal work, but rather, an attempt to extend the idea of this work in a new direction.

Re-inventing the Wheel

Depending on your viewpoint, I was blessed or cursed with a poor memory. When I studied math and physics, I never tried to remember formulas, but rather derived them as needed. I tried to understand rather than remember. Rather than try to remember the rules of a programming language, I try to understand the language, and look up rules in the manual as needed.

When I began learning design patterns (in the summer of 2000), I did the same thing. I tried to understand, rather than to remember. I tried to comprehend the basic ideas rather than the specific patterns. When I wrote code, I tried applying a couple of specific patterns, but more often, I attempted to use the ideas. I "made up" solutions which turned out to be the same or very similar to design patterns in the books. Some would call this "re-inventing the wheel". I agree.

I believe that this technique is helping me to develop a way of thinking. I "discover" that I have used a particular pattern after the fact. This seems contrary to some of the suggestions in the GoF book, but for me, it seems to work fine. As I continue, I expect to "invent" more existing patterns and probably some patterns which do not exist yet.

Back to top

Abstracting the Ideas

Since I knew I couldn't remember all the patterns in the GoF book (even though there are only 23) I put together a summary page which is in a table format and includes for each pattern:

The last "column" was an afterthought. As I re-read the introduction, I realized that there were many ideas as opposed to patterns embedded in the book. The sources were the introduction and the conclusion of each of the main chapters. I put together another document, which has several sections: As I put together the "ideas" doc, I gradually filled in the "Ideas" column in the overview table.

The GoF book presents these ideas, but not with the kind of organization they used to present the patterns. It offers no clue as to how to develop a way of thinking from the ideas and patterns.

I spent a substantial amount of time studying and refining these two documents. My purpose was to learn the ideas behind the patterns and to develop a way of thinking.

Back to top

Examples

I have included some examples to illustrate some points. In an effort to keep this article reasonably short and yet to provide full source, I am not including source in this document. Where reasonable, I am providing full source:

The text of this section is aimed at explaining my (alleged) thought processes which led to certain design decisions. I am trying to show how I am attempting to develop a way of thinking.

Back to top

XML Parser

In the summer of 2000, I was reading the GoF book for the first time and concurrently trying to learn XML. Since I hadn't yet discovered the DOM (org.w3c.dom) or the many freeware parsers available, I thought it would be helpful to write an XML parser! By proceeding entirely on my own, I re-invented the DOM wheel. The interfaces I came up with are not too different from the DOM, but I added the ability to accept a Visitor.

I used the GoF Visitor pattern as the "model" for my XmlVisitor class, which is the "base" class for any specific visitors. I quickly realized that there was no easy way to invoke the visitor, so I added something to the pattern. I put a visitXml method into the XmlVisitor class.

The visitXml method is the only public method in XmlVisitor. It is the only one needed. Once the XML structure is built and the XmlVisitor subclass instantiated, simply invoke the visitXml method on the subclass (which will default to the base class, since this method should not be overridden).

The zip file contains all the source for this project. It works on the test files provided. More important, it clearly illustrates my first attempt at using a design pattern.

Although this entire project got scrapped once I discovered the DOM, I learned a lot from it. In particular, I had my first experience with using a design pattern. I also had some interesting ideas about how I might have proceded with it; see the following section ("Double Visitor").

Back to top

Double Visitor

In the course of working on my XML parser (see above), I realized that I needed a way to "apply" one XML structure to another. I came up with the idea of the Double Visitor as a solution. The zip file contains the HTML file and supporting gif files for an unfinished design pattern. I think that there is just enough to give a good idea of how it might work.

There was never any source for this; I never got that far. I include this because it shows some of my thoughts on how to solve a particular problem. In retrospect, this is probably not the best solution, but it is an early attempt at an original(?) design pattern.

Back to top

EBNF

This is another odd byway in my XML parser saga. At this point, I had a (somewhat) working XML parser, but it didn't recognize all possible forms as specified by the XML specification. The XML specs contained "rules" in the EBNF language for recognizing XML. I thought if I could read in these rules and parse them into some kind of structure, then I could apply them to an XML document to parse it!

In retrospect, I don't think the idea would have worked, but it was an attempt to implement the Interpreter pattern from the GoF book. The zip file contains whatever source and other files I had for that project. It may prove instructive to see how I was trying to implement a pattern. Then again, it may not. Thus ends the saga of my XML parser.

Back to top

XMidi

My interest in music and computers has led me to some interesting byways. It seems to me that there are various ways of representing music in computers, among them midi and "notation-based".

Midi was designed to allow electronic instruments to communicate. Once computers came into the picture, a midi file format was developed. Midi data is meant to support music performance rather than notation. You can record a performance on electronic instruments using a computer and midi recorder (sequencer). This recording will capture most (if not all) sound aspects of the performance.

The midi format is not aimed at music notation. There are several programs aimed at music notation but each uses its own format for files. These formats are not interchangeable, and they are usually proprietary, which means that it is difficult to figure out how to get data from these files without using the program which created them.

One problem is that there is no good way to go from one notation program to another. Another problem is that there is no good way to go between notation programs and performance programs. The midi file format is usually the "common" format between these various programs, but not enough data is retained.

It occurred to me that this might be a job for XML. I envisioned two XML formats: XMidi and XMusic, for performance and notation data, respectively. I designed first drafts of both, and began work on a program which would allow conversion between a midi file and XMidi. Since the midi file format is known, this is not an impossible task.

One small note. The name "XMidi" turns out to have been unfortunate. There are several other uses of the name, none of which has anything to do with mine.

I set out to write my XMidi program. By this time, I had discovered the DOM. I also knew that there were several good freeware parsers available. This is when I put my XML parser on the shelf. I decided that I would use one of the available parsers, but I didn't want to be tied down to any one particular parser.

I decided that there should be a way to use just about any parser without any specific reference in the code. The choice of parsers should be a run-time choice. I made a plan.

The crux of the plan is the Parser interface. It defines a couple of methods. An implementing class will be a "helper" class in the sense that it will help my program talk to a parser. The zip file contains three helper classes: JAXP, Xerces, and XSilfide. These support three of the major parsers. Each of these classes imports the classes needed from the parser and implements the methods needed to allow parsing of an XML document.

When I came up with this idea, it occurred to me that it was very much along the lines of the design patterns, but to this day, I am still not sure which pattern it follows. It has aspects of Proxy and Strategy. It may be an example of Delegate (described in the GoF book, but not part of their "catalog"). Or it may be a new pattern. Perhaps someone can tell me. I am less concerned with which pattern I re-invented or even if I came up with a new pattern. What matters is that I was able to invent a pattern-like solution, which was not just like any that I had read about. This represents an important step towards the development of a way of thinking.

Looking towards the future, I don't see how I can go much further with this project without some help. The XMidi format took shape as I wrote the code to go from a midi file to XML. The DTD grew with the code. I would love to get to the software companies which write the major notation programs and convince them that they need XMusic (or at least some XML format for music notation.) If the major companies allowed data to be exported to and imported from XML, then we would have a medium of exchange of music notation. Once this is settled, then we could begin to work on ways of going between XMidi and XMusic! Now there's a project!

Back to top

DateBox

I was recently working on a (commercial) project in which I was trying to make a GUI which was similar to some screen shots of another GUI. One aspect of this GUI which caught my eye was a date field with a little "arrow" button (like a combo box). When the user clicked the button, a calendar popped up. The user could select any day from the calendar to fill the date field.

My client ran out of money before I got to implementing this particular widget, but I decided to write it on my own time for my own education.

On the first pass, I simply assumed that all dates in the date field would be in the MM/DD/YYYY form. Once I had everything working, I realized that some users might prefer other forms, and different uses of the widget might be better suited to other date formats. I thought about the question of date formats and came up with a solution.

I wrote the DateFormatter class as a base class. It is an abstract class, but with both abstract and non-abstract methods. (This is allowed in Java.) The abstract methods are for the subclasses to implement. The non-abstract methods (all static) are "utility" methods which support the whole idea. The two abstract methods allow conversions between a string representation of a date and three integers (for the month, day, and year). Subclasses of DateFormatter implement these two methods for the particular date format they support. The zip file contains two subclasses, DFSlash (for MM/DD/YYYY) and DFHyphen (for YYYY-MM-DD). Both reside in DateFormatter.java, but should probably be broken out into their own files so they could be public classes.

One of the utility methods is called DFFactory. It takes a string which is the fully qualified name of a DateFormatter subclass, and returns an instance of that class. As the name implies, this was a conscious effort to use the GoF Factory Method pattern.

But when we look at the DateFormatter and its subclasses from the client perspective, we see that the client can use the static factory method to obtain an instance of the DateFormatter subclass which supports the desired date format. Within the package, both DateBox.java and PalCal.java share a subclass of DateFormatter, which can be selected at runtime with a parameter.

I think that this is an example of the GoF Strategy pattern, but this is an after-thought. At the time I wrote it, I was simply trying to find a good solution to a problem. I think I am beginning to develop a way of thinking.

Back to top

Conclusion

I have tried to suggest that there is a way of thinking about programming beyond design patterns. I have tried to show how I have been trying to develop this way of thinking.

I would appreciate any
feedback from any interested parties.

Back to top

References

Back to top