裝飾模式:在不必改變原類文件和使用繼承的情況下,動(dòng)態(tài)的擴(kuò)展一個(gè)對象的功能。它是通過創(chuàng)建一個(gè)包裝對象,也就是裝飾來包裹真實(shí)的對象。就增加功能來說,Decorator模式相比生成子類更加靈活。
角色分析:
1、組件對象的接口:可以給這些對象動(dòng)態(tài)的添加指責(zé);
2、所有裝飾器的父類:需要定義一個(gè)與組件接口一致的接口,并持有一個(gè)Component對象,該對象其實(shí)就是被裝飾的對象;
3、具體的裝飾器類:實(shí)現(xiàn)具體要向被裝飾對象添加的功能。用來裝飾具體的組件對象或者另外一個(gè)具體的裝飾器對象。
適用性:
1、需要?jiǎng)討B(tài)的給一個(gè)對象添加功能,這些功能可以再動(dòng)態(tài)地撤銷;
2、增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能,從而使繼承關(guān)系變的不現(xiàn)實(shí)。
3、當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時(shí)。一種情況是,可能有大量獨(dú)立的擴(kuò)展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長。另一種情況可能是因?yàn)轭惗x被隱藏,或類定義不能用于生成子類。
優(yōu)點(diǎn):
1、Decorator模式與繼承關(guān)系的目的都是要擴(kuò)展對象的功能,但是Decorator可以提供比繼承更多的靈活性。
2、通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設(shè)計(jì)師可以創(chuàng)造出很多不同行為的組合。
缺點(diǎn):
1、這種比繼承更加靈活機(jī)動(dòng)的特性,也同時(shí)意味著更加多的復(fù)雜性。
2、裝飾模式會導(dǎo)致設(shè)計(jì)中出現(xiàn)許多小類,如果過度使用,會使程序變得很復(fù)雜。
3、裝飾模式是針對抽象組件類型編程。但是,如果你要針對具體組件編程時(shí),就應(yīng)該重新思考你的應(yīng)用架構(gòu),以及裝飾者是否合適。當(dāng)然也可以改變抽象組件接口,增加新的公開的行為,實(shí)現(xiàn)“半透明”的裝飾者模式。
例:
/**
*輸出一個(gè)字符串
*裝飾器動(dòng)態(tài)添加功能
*Class EchoText
*/
class EchoText
{
??? protected $decorator = [];
??? public function Index()
??? {
??????? //調(diào)用裝飾器前置操作
??????? $this->beforeEcho();
??????? echo "你好,我是裝飾器";
??????? //調(diào)用裝飾器后置操作
??????? $this->afterEcho();
??? }
??? //增加裝飾器
??? public function addDecorator(Decorator $decorator)
??? {
??????? $this->decorator[] =$decorator;
??? }
??? //執(zhí)行裝飾器前置操作 先進(jìn)先出原則
??? protected function beforeEcho()
??? {
??????? foreach($this->decorator as $decorator)
??????????? $decorator->before();
??? }
??? //執(zhí)行裝飾器后置操作 先進(jìn)后出原則
??? protected function afterEcho()
??? {
??????? $tmp=array_reverse($this->decorator);
??????? foreach($tmp as $decorator)
??????? {
??????????? $decorator->after();
??????? }
??? }
}
//裝飾器接口
interface decorator
{
??? public function before();
??? public function after();
}
/*
*顏色裝飾器實(shí)現(xiàn)
*ClassColorDecorator
*/
class ColorDecorator implements Decorator
{
??? protected $color;
??? public function __construct($color)
??? {
??????? $this->color=$color;
??? }
??? public function before()
??? {
??????? echo "<div style='color':{$this->color}>";
??? }
??? public function after()
??? {
??????? echo "</div>";
??? }
}
/*
*字體大小裝飾器
*Class SizeDecorator
*/
class SizeDecorator implements Decorator
{
??? protected $size;
??? public function __construct($size)
??? {
??????? $this->size = $size;
??? }
??? public function before()
??? {
??????? echo "<div style='font-size:{$this->size}px'>";
??? }
??? public function after()
??? {
??????? echo "</div>";
??? }
}
//實(shí)例化輸出類
$echo = new EchoText();
//增加顏色裝飾器
$echo->addDecorator(new ColorDecorator('red'));
//增加大小裝飾器
$echo->addDecorator(new SizeDecorator('22'));
//輸出
$echo->Index();