Hack68.Create Objects with Abstract Factories


Hack 68. Create Objects with Abstract Factories

Use an Abstract Factory pattern to control what type of object is created.

The Abstract Factory pattern is the vending machine of design patterns. You ask it for what you want, and it vends you an object based on your criteria. The value is that you can change what types of objects are created throughout the system by altering just the factory.

The super-simple factory in this example creates Record objects, where each record has an ID, a first name, and a last name. The relationship between these classes is shown in Figure 7-2.

Figure 7-2. The Record and the RecordFactory classes


Factory objects often create more than one type of object. To keep this example simple, though, I've limited the factory to creating only a single object type.


There is no way to strictly enforce that only the factory can create objects of a particular type in PHP. But if you use a factory often enough, engineers copying and pasting your code will end up using the factory; it will quickly become the de facto way of creating the different types of objects.

7.3.1. The Code

Save the code in Example 7-2 as abs_factory.php.

Example 7-2. An Abstract Factory pattern example
 <?php class Record {   public $id = null;   public $first = null;   public $last = null;   public function __construct( $id, $first, $last )   { $this->id = $id; $this->first = $first; $this->last = $last;    }   }   class USRecord extends Record   { public $addr1 = null; public $addr2 = null; public $city = null; public $state = null; public $zip = null; public function __construct( $id, $first, $last, $addr1, $addr2, $city, $state, $zip ) {     parent::__construct( $id, $first, $last ); $this->addr1 = $addr1; $this->addr2 = $addr2; $this->city = $city; $this->state = $state; $this->zip = $zip; }    }    class ForeignRecord extends Record    {   public $addr1 = null;   public $addr2 = null;   public $city = null;   public $state = null;   public $postal = null;   public $country = null;   public function __construct( $id, $first, $last, $addr1, $addr2, $city, $state, $postal, $country )   { parent::__construct( $id, $first, $last );   $this->addr1 = $addr1;   $this->addr2 = $addr2;   $this->city = $city;   $this->state = $state;   $this->postal = $postal;   $this->country = $country;   } } class RecordFactory { public static function createRecord( $id, $first, $last, $addr1, $addr2, $city, $state, $postal, $country ) { if ( strlen( $country ) > 0 && $country != "USA" ) return new ForeignRecord( $id, $first, $last, $addr1, $addr2, $city, $state, $postal, $country ); else return new USRecord( $id, $first, $last, $addr1, $addr2, $city, $state, $postal ); } } function readRecords() { $records = array(); $records []= RecordFactory::createRecord( 1, "Jack", "Herrington", "4250 San Jaquin Dr.", "", "Los Angeles", "CA", "90210", "" ); $records []= RecordFactory::createRecord(  1, "Megan", "Cunningham", "2220 Toorak Rd.", "",  "Toorak", "VIC", "3121", "Australia" ); return $records; } $records = readRecords(); foreach( $records as $r ) { $class = new ReflectionClass( $r ); print $class->getName()." - ".$r->id." - ".$r->first." - ".$r->last."\n"; } ?> 

The first section of the code implements the Record base class, as well as the USRecord and ForeignRecord derived classes. These are all fairly simple data structure wrappers. Then the factory class can build either a USRecord or a ForeignRecord depending on the data being passed in. The test code at the end of the script adds a few records, and then prints out their type along with some of their data.

7.3.2. Running the Hack

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

 % php abs_factory.php USRecord - 1 - Jack - Herrington ForeignRecord - 1 - Megan - Cunningham 

You can use the Abstract Factory pattern in a PHP database application in several ways:


Database object creation

The factory vends any of the object types associated with the different tables in the database.


Portable object creation

The factory vends a number of different objects depending on either the type of operating system the code is being run on or the different databases that the application is attaching itself to.


Creation by standard

The application supports various file format standards and uses the factory to create an object appropriate to the given file type. File readers can register themselves with the factory to add file support without having to change any downstream clients.

After using patterns for a while, you will develop a sense for when it makes sense to use a particular pattern. You would use this pattern when you are doing an awful lot of object construction with various types of objects. You will find that if you ever need to change what types of objects are created, or how they are created, you will have a lot of code to change. If you use a factory, you will need to change that object creation in only one place.

7.3.3. See Also

  • "Flexible Object Creation with Factory Methods" [Hack #69]



PHP Hacks
PHP Hacks: Tips & Tools For Creating Dynamic Websites
ISBN: 0596101392
EAN: 2147483647
Year: 2006
Pages: 163

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net