<?php abstract class Tile{ abstract function getWealthFactor(); } class Plains extends Tile{ private $wealthfactor=2; function getWealthFactor(){ return $this->wealthfactor; } } abstract class TileDecorator extends Tile{ protected $tile; function __construct(Tile $tile){ $this->tile = $tile; } } class DiamondDecorator extends TileDecorator{ function getWealthFactor(){ return $this->tile->getWealthFactor()+2; } } class PollutionDecorator extends TileDecorator{ function getWealthFactor(){ return $this->tile->getWealthFactor()-4; } } //客户端调用 $tile = new Plains(); echo $tile->getWealthFactor(); //输出2 $tile = new DiamondDecorator(new Plains()); echo $tile->getWealthFactor(); //输出4 $tile = new PollutionDecorator(new DiamondDecorator(new Plains())); echo $tile->getWealthFactor(); //输出0 ?>
装饰模式比继承更加灵活
装饰模式使用组合和委托而不是只是使用继承来解决功能的变化问题(组合优于继承的原则,因为不断继承,会让代码变得很庞大)。例如我们上面的客户端调用例子3,如果我们按照之前的老方法不断继承,我们需要创建一个类Diamond类,还要创建一个Pollution类,才可以达到我们既实现获得Diamond又获得Pollution的功能。如果我们采用装饰模式,就可以灵活的组合了。例如我们还可以创建一个SeaDecorator类,然后这样调用new PollutionDecorator(new SeaDecorator(new Plains())),也可以这样调用new DiamondDecorator(new SeaDecorator(new Plains())),依次类推,使用组合,犹豫继承,下面是它的UML图解: