Recursive Builder Pattern

In this Internet age, everybody publishes information and creates applications using HTML. And so do you. So you've got some interesting data to show the world, you read it from a database... and then? You find the BuilderPattern in the GangOfFour DesignPatterns book. And you decide that that's how you will build your HTML pages. Your HTMLPageBuilder class will have methods startPage(), endPage(), startForm(), endForm(), addSubmitButton(), etc. [Let's assume you're using Java.]

Then you notice that the builder has many startXYZ() / endXYZ() methods. Both of these usually need access to the same information; but whether they really need it at all depends on the specific HTML that is generated. And: you always have to make sure that you have an endXYZ() for every startXYZ().

In general, every time you build a recursive structure, the same thing occurs. Isn't there a nicer interface for the builder? Yes there is.

Therefore, use the Command pattern, and pass the builder a Command object which builds the internals of a given part of the structure.

In the example, give the builder methods like "buildPage(String title, ICommand command)". (Here ICommand is a simple interface with just a single "void execute()" method.) At the place where buildPage() needs to build the internals of the page, it calls "command.execute()". This command then calls other buildXYZ() methods as appropriate.

When working in Java, this is nicely combined with the 'anonymous classes' feature of Java 1.1, where you can use expressions like "new ICommand() { public void execute() { /*some code*/ } }".

When working in Smalltalk, you of cource don't need an ICommand interface-- just use a Block. The message then becomes "buildPageTitled: aTitle around: aBlock".

And so you end up coupling shed loads of code to your current page layout, which marketing will want to change quite soon. XML/XSL parsers can help solve this problem, as can templating systems such as WebMacro.

Related question: I re-read the GoF BuilderPattern, and noted two related remarks which seem contradictory to me. In the "Implementation" section (p. 101) they say in point 2:

Tree structures such as parse trees that are built bottom-up are another example. In that case, the builder would return child nodes to the director, which then would pass them back to the builder to build the parent nodes.

Which is of course an alternative for the RecursiveBuilderPattern. But then I started wondering about the datatype of the child nodes that the builder would return. And the GoF goes on to say in implementation issue 3:

In the common case, the products produced by the concrete builders differ so greatly in their representation that there is little to gain from giving different products a common parent class.

Eh? So what would be the type of the nodes that the builder creates? Isn't this a contradiction? -- MarnixKlooster

I think it is extremely important in know when to use TechnologiesOverPatterns.

Can you clarify this? -- MarnixKlooster

Yes, sometiems instead of using Patterns, it makes more sense to use Perl, or XML, or grammer-generator. I love Patterns and use them all the time. But I'm also mature enough to know when not to use them.

View edit of February 26, 2006 or FindPage with title or text search