I am extremely late in writing this article. I hope readers will realise that I have had rather a busy time over the last few weeks. One result is that this article is going to be less well researched and tested than usual. Indeed, I am going to focus almost entirely on what these two patterns are without concerning myself much with coding issues.
Builder and Factory Method are patterns that are concerned with decoupling interfaces from implementations. However they differ in at least one critical fashion and that is in the nature of the object they are used to produce. In both cases we are likely to be dealing with very flat hierarchies. Typically a base class providing the interface that is the direct base of a number of concrete classes.
The Factory Method Pattern itself has two main forms in addition to an increasingly common major variation. On the other hand the Builder Pattern is used to create complicated objects with internal structure that needs to be built up piecemeal.
Well the above is an overly brief summary of what the GoF book has to say. In fact I find this book particularly irritating when addressing these patterns because of the lack of detail. I thought I understood the FM pattern till I hauled out the GoF book. By the time I had finished reading the relevant chapter I was completely confused.
Let me expose my ignorance by trying to explain what I understand by the FM pattern.
In a typical case I have persistent data stored away on my disk that relates to members of a suitable hierarchy. For example, I might have a list of names and addresses in which the addresses were for different countries. Those of us who carry out international mailings know that address format vary substantially from country to country. The USA has zip codes and two letter abbreviations for States, the UK has postcodes which is all that is required as part from the street address. Other countries have other systems.
Now it seems reasonable to subclass the concept of a postal address to meet the different national requirements. When I come to read the data from backing store I need a mechanism to create the right kind of object for the data. One way of doing this is to store some kind of type ID at the start of each address. Then recreating items in dynamic storage amounts to calling a FM to create an instance of the correct subclass into which the relevant data can be read.
Actually this example also exemplifies the problem of copying and changing addresses. If someone moves from the UK to the USA their address not only changes but the type of the address does as well. The way I handle this is to design a handle class that provides the interface to the client while delegating the work to a hierarchy of address types. One thing the handle class needs is a FM object to create the specific instances to which the handle's pointer can be set. The base class of my address hierarchy is an ABC, but it includes a static factory method that creates the address instances.
Now what I would very much appreciate is for readers to write up examples of other kinds of FM pattern. In particular I would like to see an example of what the GoF describes as an abstract creator class without any implementation of the factory method it declares. I would also be interested in seeing clearly documented examples of several parameterised factory methods (these will be done via templates in C++).
It may all be glaringly obvious to you, but it isn't to me and I guess that means that it isn't for quite a large number of others.
Now let me write briefly about the Builder pattern. As I understand it, this is appropriate when you need to build an object out of a number of pieces. Furthermore there are multiple implementations of the pieces. Let me stick the GoF's maze example. A maze can be implemented in a variety of ways: it can be a simple drawing, it can be a pattern of tiles on a floor, it can be made from hedges, it can be built from solid walls with doors etc. We could sit down and decide how to specify a maze. Having done so we could apply those specifications to create mazes of several different physical kinds even though they would be no more than alternative manifestations of the same maze.
If I understand the idea of the Builder pattern correctly, it could be used by creating a base class that provided polymorphic functions to provide each of the primitive functions (make corridor, T-junction, left-turn etc.) The derived concrete classes (hedge-maze, brick-maze, tile-maze etc.) would provide the functionality to implement each of those maze features.
Now we can instantiate Builder in some way (passing a parameter to its constructor, or by making Builder a template) so that the specific instance knows what type of maze it creates. Or we could delay that decision until we call a Makemaze member of our Builder class. However we provide that detail the result will be that the Makemaze function can read in the specifications for a maze and create an object that is of the correct type.
Now we could do something similar with our persistent database. If we have some way of packaging the data for a record (that is another topic) we could create a Builder class that read in the data for a record and created a suitable container as it went. For example if we prefixed each element of a record with an identifier that specifies the kind of field required to hold the following data the Builder could read in the data element by element and finish with a record that had the exact requirements for the specific data.
It seems to me that this kind of use for Builder is more a method for building complicated data structures than one to allow alternative implementations. But again more examples would help.
I am profoundly unhappy with both what I have written and what I read. Patterns should encapsulate good design ideas and provide some clear guidance for their implementation. I think the above will show that I think we need some rather more digestible description for the benefit of ordinary programmers. If you think you have a clear understanding of at least one implementation of either Factory Method or Builder, please take the time out to write it up for the benefit of other readers.
Overload Journal #32 - Jun 1999 + Design of applications and programs
|Browse in :||
All > Topics > Design (179)
Any of these categories - All of these categories