概念:通过装饰器可以动态的给某个对象添加属性的功能
例:奶茶,可以选择珍珠奶茶,咖啡奶茶,柠檬奶茶等。每一个都是一个类,继承自装饰器类
茶基类, 奶茶类,抽象装饰类继承自茶基类,珍珠类继承装饰器,咖啡类继承装饰器,通过构造注入的方式给奶茶类添加不同的品味。
<?php
//抽象类
abstract class Tea
{
private $description = 'unknown Tea';
public abstract function getDescription();
public abstract function getCost();
}
//普通继承
class MilkTea extends Tea
{
public function getDescription(){
return $this->description = '奶茶';
}
public function getCost(){
return 3.0;
}
}
//装饰者抽象类
abstract class CondimentDecorator extends Tea
{
}
//珍珠奶茶装饰器
class Pearl extends CondimentDecorator
{
private $_tea;
public function __construct(Tea $tea){
$this->_tea = $tea;
}
public function getDescription(){
return '珍珠' . $this->_tea->getDescription();
}
public function getCost(){
return 10 + $this->_tea->getCost();
}
}
//咖啡奶茶装饰器
class Coffee extends CondimentDecorator
{
private $_tea;
public function __construct(Tea $tea){
$this->_tea = $tea;
}
public function getDescription(){
return '咖啡' . $this->_tea->getDescription();
}
public function getCost(){
return 20 + $this->_tea->getCost();
}
}
class Lemon extends CondimentDecorator
{
private $_tea;
public function __construct(Tea $tea){
$this->_tea = $tea;
}
public function getDescription(){
return "柠檬" . $this->_tea->getDescription();
}
public function getCost(){
return 30 + $this->_tea->getCost();
}
}
//=======================================================================================
//装饰器模式测试
//
class TestDecorator
{
public static function main(){
//普通奶茶
$tea = new MilkTea();
echo $tea->getDescription() . '价格为:¥' . $tea->getCost() . "</br>"; // 奶茶价格为:¥3
//装饰器奶茶
$tea2 = new MilkTea(); //普通奶茶
$tea2 = new Coffee($tea2); //咖啡奶茶
$tea2 = new Pearl($tea2); //珍珠咖啡奶茶
$tea2 = new Lemon($tea2); //柠檬珍珠咖啡奶茶
echo $tea2->getDescription() . '价格为:¥' .$tea2->getCost() . "</br>"; //柠檬珍珠咖啡奶茶价格为:¥63
}
}
require 'decorator.php';
TestDecorator::main();