PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

CHAPTER 10 ■ PATTERNS FOR FLEXIBLE OBJECT PROGRAMMING


function bombardStrength() {
return 4;
}
}


I do not want to make it possible to add a Unit object to an Archer object, so I throw exceptions if
addUnit() or removeUnit() are called. I will need to do this for all leaf objects, so I could perhaps improve
my design by replacing the abstract addUnit()/removeUnit() methods in Unit with default
implementations like the one in the preceding example.


abstract class Unit {
abstract function bombardStrength();


function addUnit( Unit $unit ) {
throw new UnitException( get_class($this)." is a leaf" );
}


function removeUnit( Unit $unit ) {
throw new UnitException( get_class($this)." is a leaf" );
}
}


class Archer extends Unit {
function bombardStrength() {
return 4;
}
}


This removes duplication in leaf classes but has the drawback that a Composite is not forced at
compile time to provide an implementation of addUnit() and removeUnit(), which could cause
problems down the line.
I will look in more detail at some of the problems presented by the Composite pattern in the next
section. Let’s end this section by examining of some of its benefits.



  • Flexibility: Because everything in the Composite pattern shares a common
    supertype, it is very easy to add new composite or leaf objects to the design
    without changing a program’s wider context.

  • Simplicity: A client using a Composite structure has a straightforward interface.
    There is no need for a client to distinguish between an object that is composed of
    others and a leaf object (except when adding new components). A call to
    Army::bombardStrength() may cause a cascade of delegated calls behind the
    scenes, but to the client, the process and result are exactly equivalent to those
    associated with calling Archer::bombardStrength().

  • Implicit reach: Objects in the Composite pattern are organized in a tree. Each
    composite holds references to its children. An operation on a particular part of the
    tree, therefore, can have a wide effect. We might remove a single Army object from
    its Army parent and add it to another. This simple act is wrought on one object, but
    it has the effect of changing the status of the Army object’s referenced Unit objects
    and of their own children.

  • Explicit reach: Tree structures are easy to traverse. They can be iterated through in
    order to gain information or to perform transformations. We will look at a
    particularly powerful technique for this in the next chapter when we deal with the
    Visitor pattern.

Free download pdf