平时很少用到装饰者模式,一直想不到装饰者模式用在什么地方,突然想到
可以用在游戏中有各种各样的属性的装备上。
装饰者模式的关键就是装饰者对象和被装饰的对象必须是同一类型,这样,才能在一层层添加属性的时候,不改变原有对象的类型
既然是游戏中的武器装备,那么首先得创建一个武器基类
abstract class Weapon
{
abstract public function description();
abstract public function cost();
}
所有武器必须继承此基类,并自行实现武器的描述和武器的价格
创建武器:剑类
class Glave extends Weapon
{
public function cost ()
{
return 100;
}
public function description ()
{
return 'Glave';
}
}
创建武器:匕首类
class Knife extends Weapon
{
public function cost ()
{
return 80;
}
public function description ()
{
return 'Knife';
}
}
创建武器:斧子类
class Axe extends Weapon
{
public function cost ()
{
return 120;
}
public function description ()
{
return 'Axe';
}
}
武器有了,武器的属性定义三种:力量,敏捷,智力
但是在此之前,为了不改变包装的装备类型,需要给武器属性定义一个基类,即装饰者类
class Property extends Weapon
{
/**
* 装备引用
* @var Weapon
*/
protected $_weapon = null;
protected $_price = 0;
protected $_description = '';
public function __construct(Weapon $weapon)
{
$this->_weapon = $weapon;
}
public function cost ()
{
return $this->_weapon->cost() + $this->_price;
}
public function description ()
{
return $this->_weapon->description().','.$this->_description;
}
}
下面定义武器属性:力量,敏捷,智力继承自武器属性(装饰者)类
力量属性类
class Strength extends Property
{
protected $_price = 250;
protected $_description = '+25 strength';
}
敏捷属性类
class Agility extends Property
{
protected $_price = 300;
protected $_description = '+30 agility';
}
智力属性类
class Intellect extends Property
{
protected $_price = 200;
protected $_description = '+20 intellect';
}
下面来看看,生成各种属性的装备
function __autoload($class)
{
require_once "{$class}.php";
}
// 加敏捷加力量的斧子
$weapon = new Agility(new Strength(new Axe()));
echo 'Description:',$weapon->description(),' Cost:$',$weapon->cost();
echo '<br />';
// 加智力加敏捷的匕首
$weapon = new Agility(new Intellect(new Knife()));
echo 'Description:',$weapon->description(),' Cost:$',$weapon->cost();
echo '<br />';
// 加双倍力量的剑
$weapon = new Strength(new Strength(new Glave()));
echo 'Description:',$weapon->description(),' Cost:$',$weapon->cost();
运行结果如下:
Description:Axe,+25 strength,+30 agility Cost:$670
Description:Knife,+20 intellect,+30 agility Cost:$580
Description:Alave,+25 strength,+25 strength Cost:$600
虽然一个装备经历了一个又一个属性的叠加,但是装备的类别并没有变,剑还是剑,斧子还是斧子。
所以装备属性(装饰者)必须继承自武器类,即使经过属性装饰,返回的还是武器。
装备属性类(装饰者)虽继承自武器类,但是还是得封装一些装饰者有关的操作。