PHP Hacks Free Open Book

PHP Hacks

Previous Page
Next Page

Hack 70. Abstract Construction Code with a Builder

Use the Builder pattern to abstract code that performs a routine construction task, such as composing HTML or text for an email.

I've always found that code that constructs something is some of the most elegant code in a system. I suppose that's just because I spent a year writing a book on code generation, which is all about constructing code.

By the way, the book is Code Generation in Action (Manning). It_s still available and makes an excellent holiday gift for friends and family.


An example of construction code is the code that reads an XML document off the disk and constructs an in-memory representation of that structure. Another is a module of code that constructs an email message to tell a customer she is behind on her payments.

It's the late-payment mail that I want to focus on in this hack; but I'm going to do it with a twist. I'm going to use the Builder pattern so that the same code that creates a message in HTML can also create a message in XHTML or text format.

I'm going to have the code that writes the past-due notice use a builder instead of just creating the string directly. This builder object will have a set of methods, as shown in Figure 7-4. The startBody( ) and endBody() methods wrap the creation of the message. The addText() method adds some text, and the addBreak( ) method adds a line break.

Figure 7-4. The output builder hierarchy


The OutputBuilder abstract class has several concrete instantiations. One is HTMLBuilder, which builds HTML. Deriving from that is XHTMLBuilder, which alters the behavior of its parent just enough to make the output XHTML compliant. And finally there's TextBuilder, which builds a plaintext representation of the message.

7.5.1. The Code

Save the code in Example 7-4 as builder.php.

Example 7-4. A set of example builder classes and some test code
	<?php
	abstract class OutputBuilder
	{
	  abstract function getOutput();
	  abstract function startBody();
	  abstract function endBody();
	  abstract function addText( $text );
	  abstract function addBreak();
	}

	class HTMLBuilder extends OutputBuilder
	{
	  private $buffer = "";

	  public function getOutput()
	  {

	    return "<html>\n".$this->buffer."\n</html>\n";
	  }
	  public function startBody() { $this->add( "<body>" ); }
	  public function endBody() { $this->add( "</body>" ); }
	  public function addText( $text ) { $this->add( $text ); }
	  public function addBreak() { $this->add( "<br>\n" ); }

	  protected function add( $text ) { $this->buffer .= $text; }
	}
	
	class XHTMLBuilder extends HTMLBuilder
	{
	  public function addBreak() { $this->add( "<br />\n" ); }
	}

	class TextBuilder extends OutputBuilder
	{
	  private $buffer = "";

	  public function getOutput()
	  {
	    return $this->buffer."\n";
	  }
	  public function startBody() { }
	  public function endBody() { }
	  public function addText( $text ) { $this->add( $text ); }
	  public function addBreak() { $this->add( "\n" ); }

	  protected function add( $text ) { $this->buffer .= $text; }
	}
	
	function buildDocument( $builder )
	{
	  $builder->startBody();
	  $builder->addText( 'Jack,' );
	  $builder->addBreak();
	  $builder->addText( 'You owe us $10,000. Have a NICE day.' );
	  $builder->endBody();
	}

	print "HTML:\n\n";

	$html = new HTMLBuilder();
	buildDocument( $html );
	echo( $html->getOutput() );
	print "\nXHTML:\n\n";

	$xhtml = new XHTMLBuilder();
	buildDocument( $xhtml );
	echo( $xhtml->getOutput() );

	print "\nText:\n\n";

	$text = new TextBuilder();
	buildDocument( $text );
	echo( $text->getOutput() );
	?>

7.5.2. Running the Hack

You run this hack on the command line using the PHP command-line interpreter:

	% php builder.php
	HTML:

	<html>
	<body>Jack,<br>
	You owe us $10,000. Have a NICE day.</body>
	</html>

	XHTML:

	<html>
	<body>Jack,<br />
	You owe us $10,000. Have a NICE day.</body>
	</html>

	Text:

	Jack,
	You owe us $10,000. Have a NICE day.

This shows the output of the three different builders. The first is the HTML version with the correct HTML tags and the <br> tag. The XHTML tag changes the behavior slightly so that the <br> tag has become <br />. The text version is just plain text, with the break turned into a simple carriage return.

Looking at the code, you see the definition of the abstract OutputBuilder class at the start of the file, followed by the concrete instantiations for the different flavors of output. The buildDocument( ) function uses the builder to build the message. The code at the bottom of the file tests the buildDocument( ) function with each of the different flavors of builders.

You can use a Builder pattern in several places in a PHP web application:


File reading

Any time you are parsing a file, you should use a Builder pattern to abstract the parsing of the file from the creation of the in-memory data structures that hold the data in the file.


File writing

As I showed in this hack, you can use a Builder pattern to create multiple output formats from a single document-building system.


Generating code

You can use builders to generate code for any number of languages from a single generation system.

The .NET Framework uses the Builder pattern when creating HTML for the output page to allow the same control to generate multiple flavors of HTML based on the type of web browser requesting the page.

Previous Page
Next Page
Index: [SYMBOL][A][B][C][D][E][F][G][H][I][J][K][L][M][N][O][P][Q][R][S][T][U][V][W][X][Y][Z]


     Main Menu
PHP Hacks
Table of Contents
Copyright
Credits
Preface
Chapter 1.  Installation and Basics
Chapter 2.  Web Design
Chapter 3.  DHTML
Chapter 4.  Graphics
Chapter 5.  Databases and XML
Chapter 6.  Application Design
Chapter 7.  Patterns
Section 7.1.  Hacks 6778: Introduction
Hack 67. Observe Your Objects
Hack 68. Create Objects with Abstract Factories
Hack 69. Flexible Object Creation with Factory Methods
Hack 70. Abstract Construction Code with a Builder
Hack 71. Separate What from How with Strategies
Hack 72. Link Up Two Modules with an Adapter
Hack 73. Write Portable Code with Bridges
Hack 74. Build Extensible Processing with Chains
Hack 75. Break Up Big Classes with Composites
Hack 76. Simplify APIs Using a Façade
Hack 77. Create Constant Objects with Singletons
Hack 78. Ease Data Manipulation with Visitors
Chapter 8.  Testing
Chapter 9.  Alternative UIs
Chapter 10.  Fun Stuff
Colophon
Index


More Books
PHP Hacks
Processing Xml With Java - A Guide To Sax, Dom, Jdom, Jaxp, And Trax
The Koran (Holy Qur'an)
Macromedia Flash 8 Bible
Search Engine Optimization for Dummies
YouTube Traffic
PHP 5 for Dummies
Harry Potter and The Chamber of Secrets
Harry Potter and the Sorcerer's Stone
The Pilgrim's Progress
Wireless Hacks
Flash Hacks. 100 Industrial-Strength Tips & Tools
PayPal Hacks. 100 Industrial-Strength Tips and Tools
Amazon Hacks
Pdf Hacks
The Da Vinci Code
Google Hacks
The Holy Bible
Windows XP For Dummies
Harry Potter and the Half-Blood Prince
Seo Book
Upgrading and Repairing Networks
Macromedia Dreamweaver 8 UNLEASHED
Windows XP Annoyances
Windows XP Hacks
Microsoft Windows XP Power Toolkit
Teach Yourself MS Office In 24Hours
iPod & iTunes Missing Manual
PC Hacks 100 Industrial-Strength Tips and Tools
PC Overclocking, Optimization, and Tuning - 2th Edition
PC Hardware In A Nutshell 3rd Edition
PC Hardware in a Nutshell, 2nd Edition
Upgrading and Repairing PCs
Google for Dummies
MySQL Cookbook
Teach Yourself Macromedia Flash 8 In 24 Hours
PHP CookBook
Sams Teach Yourself JavaScript in 24 Hours
PHP5 Manual
Free Games Paper Airplanes
500 Juegos Gratis 500 Giochi Gratis 500 Jeux Gratuits 500 Jogos Gratis 500 Kostenlose Spiele