- 不使用繼承
- 動(dòng)態(tài)擴(kuò)展
- 不改變?cè)械念?/li>
裝飾器模式
是一種結(jié)構(gòu)型模式,它動(dòng)態(tài)的給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來(lái)說(shuō)蔬胯,Decorator模式相比生成子類更為靈活。
裝飾模式是以對(duì)客戶透明的方式動(dòng)態(tài)地給一個(gè)對(duì)象附加上更多的職責(zé)位他。這也就是說(shuō)氛濒,客戶端并不會(huì)覺(jué)得對(duì)象在裝飾前和裝飾后有什么不同。裝飾模式可以在不使用創(chuàng)造更多子類的情況下鹅髓,將對(duì)象的功能加以擴(kuò)展舞竿。
主要角色
- 抽象構(gòu)件(Component)角色:定義一個(gè)對(duì)象接口,以規(guī)范準(zhǔn)備接收附加職責(zé)的對(duì)象窿冯,從而可以給這些對(duì)象動(dòng)態(tài)地添加職責(zé)骗奖。
- 具體構(gòu)件(Concrete Component)角色:定義一個(gè)將要接收附加職責(zé)的類。
- 裝飾(Decorator)角色:持有一個(gè)指向Component對(duì)象的指針,并定義一個(gè)與Component接口一致的接口执桌。
- 具體裝飾(Concrete Decorator)角色:負(fù)責(zé)給構(gòu)件對(duì)象增加附加的職責(zé)鄙皇。
適用性
- 在不影響其他對(duì)象的情況下,以動(dòng)態(tài)仰挣、透明的方式給單個(gè)對(duì)象添加職責(zé)伴逸。
- 處理那些可以撤消的職責(zé),即需要?jiǎng)討B(tài)的給一個(gè)對(duì)象添加功能并且這些功能是可以動(dòng)態(tài)的撤消的膘壶。
- 當(dāng)不能彩生成子類的方法進(jìn)行擴(kuò)充時(shí)错蝴。一種情況是,可能有大量獨(dú)立的擴(kuò)展颓芭,為支持每一種組合將產(chǎn)生大量的子類顷锰,使得子類數(shù)目呈爆炸性增長(zhǎng)。另一種情況可能是因?yàn)轭惗x被隱藏亡问,或類定義不能用于生成子類馍惹。
- 原始類接口 Component
- 原始類接口的具體實(shí)現(xiàn)類 Concrete Component
- 裝飾器接口 Decorator
- 裝飾器接口的具體實(shí)現(xiàn) Concrete Decorator
示例2
//基類
abstract class Beverage()
{
private $description = 'Unknown Beverage';
public function getDescription()
{
return $description;
}
abstract public function double cost();
}
//實(shí)例1
class Espresso extends Beverage
{
public function __construction()
{
$this->description = "Espresso";
}
public function cost()
{
return 1.99;
}
}
//實(shí)例2
class HouseBlend extends Beverage
{
public function __construction()
{
$this->description = "HouseBlend";
}
public function cost()
{
return 0.89;
}
}
//裝飾者接口
abstract class CondimentDecorator extends Beverage
{
protected $beverage;
public function __construct(Beverage $beverage)
{
$this->beverage = $beverage;
}
abstract public function getDescription();
}
//裝飾者1
class Mocha extends CondimentDecorator
{
public function getDescription()
{
return $this->beverage->getDescription.", Mocha";
}
public function cost()
{
return .20 + $this->beverage->cost();
}
}
測(cè)試
$expressoWithMocha = new Mocha(new Espresso());
$expressoWithMocha->getDescription();
$expressoWithMocha->cost();