PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1
CHAPTER 9 ■ GENERATING OBJECTS

If the NastyBoss class does not instantiate a Minion object, where does it come from? Authors often
duck out of this problem by constraining an argument type in a method declaration and then
conveniently omitting to show the instantiation in anything other than a test context.


class NastyBoss {
private $employees = array();


function addEmployee( Employee $employee ) {
$this->employees[] = $employee;
}


function projectFails() {
if ( count( $this->employees ) ) {
$emp = array_pop( $this->employees );
$emp->fire();
}
}
}


// new Employee class...
class CluedUp extends Employee {
function fire() {
print "{$this->name}: I'll call my lawyer\n";
}
}


$boss = new NastyBoss();
$boss->addEmployee( new Minion( "harry" ) );
$boss->addEmployee( new CluedUp( "bob" ) );
$boss->addEmployee( new Minion( "mary" ) );
$boss->projectFails();
$boss->projectFails();
$boss->projectFails();
// output:
// mary: I'll clear my desk
// bob: I'll call my lawyer
// harry: I'll clear my desk


Although this version of the NastyBoss class works with the Employee type, and therefore benefits
from polymorphism, I still haven’t defined a strategy for object creation. Instantiating objects is a dirty
business, but it has to be done. This chapter is about classes and objects that work with concrete classes
so that the rest of your classes do not have to.
If there is a principle to be found here, it is “delegate object instantiation.” I did this implicitly in the
previous example by demanding that an Employee object is passed to the NastyBoss::addEmployee()
method. I could, however, equally delegate to a separate class or method that takes responsibility for
generating Employee objects. Here I add a static method to the Employee class that implements a strategy
for object creation:


abstract class Employee {
protected $name;
private static $types = array( 'minion', 'cluedup', 'wellconnected' );


static function recruit( $name ) {
$num = rand( 1, count( self::$types ) )-1;

Free download pdf