PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

CHAPTER 9 ■ GENERATING OBJECTS


But That’s Cheating!


I promised that this chapter would deal with the logic of object creation, doing away with the sneaky
buck-passing of many object-oriented examples. Yet some patterns here have slyly dodged the decision-
making part of object creation, if not the creation itself.
The Singleton pattern is not guilty. The logic for object creation is built in and unambiguous. The
Abstract Factory pattern groups the creation of product families into distinct concrete creators. How do
we decide which concrete creator to use though? The Prototype pattern presents us with a similar
problem. Both these patterns handle the creation of objects, but they defer the decision as to which
object, or group of objects, should be created.
The particular concrete creator that a system chooses is often decided according to the value of a
configuration switch of some kind. This could be located in a database, a configuration file, or a server
file (such as Apache’s directory-level configuration file, usually called .htaccess), or it could even be
hard-coded as a PHP variable or property. Because PHP applications must be reconfigured for every
request, you need script initialization to be as painless as possible. For this reason, I often opt to hard-
code configuration flags in PHP code. This can be done by hand or by writing a script that autogenerates
a class file. Here’s a crude class that includes a flag for calendar protocol types:


class Settings {
static $COMMSTYPE = 'Bloggs';
}


Now that I have a flag (however inelegant), I can create a class that uses it to decide which
CommsManager to serve on request. It is quite common to see a Singleton used in conjunction with the
Abstract Factory pattern, so let’s do that:


require_once( 'Settings.php' );


class AppConfig {
private static $instance;
private $commsManager;


private function __construct() {
// will run once only
$this->init();
}


private function init() {
switch ( Settings::$COMMSTYPE ) {
case 'Mega':
$this->commsManager = new MegaCommsManager();
break;
default:
$this->commsManager = new BloggsCommsManager();
}
}


public static function getInstance() {
if ( empty( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}

Free download pdf