装饰模式:通过在运行时合并对象来扩展功能的一种灵活机制。
这是一种比较简单的模式,在父类底下造一个装饰子类。现在我们有地形空间(Tile),平原(Plains)是地形空间的一种,然后地形空间都是被污染的与充满钻石的状态。每个地形空间都有相应的能源指数。
<?php
/**
* 装饰模式
* Created by PhpStorm.
* User: 27778
* Date: 2018/3/13
* Time: 10:51
*/
/**
* 地形空间
* Class Tile
*/
abstract class Tile{
abstract function getWealthFactor();
}
/**
* 平原
* Class Plains
*/
class Plains extends Tile{
private $wealthfactor = 2;
function getWealthFactor(){
return $this->wealthfactor;
}
}
/**
* 地形装饰者
* Class TileDecorator
*/
abstract class TileDecorator extends Tile{
protected $tile;
function __construct(Tile $tile){
$this->tile = $tile;
}
}
/**
* 钻石平原
* Class DiamondDecorator
*/
class DiamondDecorator extends TileDecorator{
function getWealthFactor(){
return $this->tile->getWealthFactor()+2;
}
}
/**
* 被污染的平原
* Class PollutionDecorator
*/
class PollutionDecorator extends TileDecorator{
function getWealthFactor(){
return $this->tile->getWealthFactor()-2;
}
}
$tile = new Plains();
print $tile->getWealthFactor();
$tile = new DiamondDecorator(new Plains());
print $tile->getWealthFactor();
$tile = new DiamondDecorator(new DiamondDecorator(new Plains()));
print $tile->getWealthFactor();
因为装饰对象作为子类的包装,所以保持基类中的方法尽可能少是很重要的。如果一个基类具有大量的特征,那么装饰对象不得不为他们包装的对象的所有public方法加上委托。就比如我们给平原设定一个随机的大小。你还可以用一个抽象的装饰类来实现,不过这依旧会带来解耦,并可能导致bug。