PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

CHAPTER 10 ■ PATTERNS FOR FLEXIBLE OBJECT PROGRAMMING


Implementation


The Composite pattern defines a single inheritance hierarchy that lays down two distinct sets of
responsibilities. We have already seen both of these in our example. Classes in the pattern must support
a common set of operations as their primary responsibility. For us, that means the bombardStrength()
method. Classes must also support methods for adding and removing child objects.
Figure 10–1 shows a class diagram that illustrates the Composite pattern as applied to our problem.


Figure 10–1. The Composite pattern


As you can see, all the units in this model extend the Unit class. A client can be sure, then, that any
Unit object will support the bombardStrength() method. So an Army can be treated in exactly the same
way as an Archer.
The Army and TroopCarrier classes are composites: designed to hold Unit objects. The Archer and
LaserCannon classes are leaves, designed to support unit operations but not to hold other Unit objects.
There is actually an issue as to whether leaves should honor the same interface as composites as they do
in Figure 1. The diagram shows TroopCarrier and Army aggregating other units, even though the leaf
classes are also bound to implement addUnit(), I will return to this question shortly. Here is the abstract
Unit class:


abstract class Unit {
abstract function addUnit( Unit $unit );
abstract function removeUnit( Unit $unit );
abstract function bombardStrength();
}


As you can see, I lay down the basic functionality for all Unit objects here. Now, let’s see how a
composite object might implement these abstract methods:


class Army extends Unit {
private $units = array();


function addUnit( Unit $unit ) {
if ( in_array( $unit, $this->units, true ) ) {
return;
}
$this->units[] = $unit;
}

Free download pdf