裝飾者模式的定義
文章鏈接:http://www.hcoding.com/?p=101
個人站點:http://www.hcoding.com/
在不必改變原類文件和使用繼承的情況下,動態地擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。
裝飾者模式把每個要裝飾的功能放在單獨的類中,并讓這個類包裝它要裝飾的對象,因此,當需要執行特殊行為時,客戶端代碼就可以在運行的時候根據需要有選擇地、按順序地使用裝飾功能包裝對象了。
圖1
使用場景
設想一下,如果我們需要創建一個在不同場合有不同著裝的學生,例如:在學校學生需要穿上校服,在舞會學生需要穿上正裝,在家學生可以裸裝(有點變態),當然,還可以學習超人把底褲穿在外面。這時候問題來了,難道我們要為每種場合編寫一個不同穿著的學生類嗎?如果我們的童鞋想要一個穿著校服褲子、正裝上衣外露的底褲怎么辦?StudentWithSchoolUniform、StudentWithFormalWear、StudentWithNaked、StudentWithSchoolUniformAndOutSideUnderWear..................綿綿無盡的類~~~累!是的,如果這樣就造成類爆炸了,需求增加,類就不斷的增加,整個系統的維護難度可想而知。
所以這時候,裝飾者模式就可以發揮它的作用了,底褲、正裝、校服、鞋子、眼鏡等等都是具體的裝飾者,學生是具體的被裝飾的對象,被裝飾的對象和裝飾者的抽象類都繼承者同一個父類。為學生穿上不同的服裝,其實就是使用裝飾者類(服裝)包裹被裝飾者類(學生),形象的說這是一個穿衣的過程。
類和接口
例子
圖2
Person.php
1 <?php 2 3 /** 4 * Person.php 5 * 被裝飾基類 6 **/ 7 abstract class Person{ 8 9 public abstract function show();10 11 }View Code
Student.php
1 <?php 2 3 /** 4 * Student.php 5 * 具體被裝飾對象 6 **/ 7 class Student extends Person{ 8 9 PRivate $name;10 11 public function __construct($name){12 $this->name = $name;13 }14 15 public function show(){16 echo '我是學生',$this->name;17 }18 }View Code
Costume.php
1 <?php 2 3 /** 4 * Costume.php 5 * 裝飾者基類 6 **/ 7 abstract class Costume extends Person{ 8 9 10 }View Code
Shirt.php
1 <?php 2 3 /** 4 * Shirt.php 5 * 具體的裝飾者類 6 **/ 7 class Shirt extends Costume{ 8 9 private $person;10 11 public function __construct(Person $person){12 13 $this->person = $person;14 15 }16 17 public function show(){18 19 echo $this->person->show(),',穿著襯衫';20 }21 22 }View Code
Pants.php
1 <?php 2 3 /** 4 * Pants.php 5 **/ 6 class Pants extends Costume{ 7 8 private $person; 9 10 public function __construct(Person $person){11 12 $this->person = $person;13 14 }15 16 public function show(){17 18 echo $this->person->show(),',穿著褲子';19 }20 21 }View Code
Glasses.php
1 <?php 2 3 /** 4 * Glasses.php 5 **/ 6 class Glasses extends Costume{ 7 8 private $person; 9 10 public function __construct(Person $person){11 12 $this->person = $person;13 14 }15 16 public function show(){17 18 echo $this->person->show(),',帶著眼鏡';19 }20 21 }View Code
UnderWear.php
1 <?php 2 3 /** 4 * UnderWear.php 5 **/ 6 class UnderWear extends Costume{ 7 8 private $person; 9 10 public function __construct(Person $person){11 12 $this->person = $person;13 14 }15 16 public function show(){17 18 echo $this->person->show(),',穿著DK';19 }20 21 }View Code
Client.php
1 <?php 2 3 require_once 'Person.php'; 4 require_once 'Costume.php'; 5 require_once 'Student.php'; 6 require_once 'UnderWear.php'; 7 require_once 'Shirt.php'; 8 require_once 'Pants.php'; 9 require_once 'Glasses.php';10 11 // Student繼承Person12 $jc = new Student('JC');13 $jc->show(); // 我是學生JC14 echo '<br>';15 16 // 用UnderWear類裝飾Person17 $underwear = new UnderWear($jc);18 $underwear->show(); // 我是學生JC,穿著DK19 echo '<br>';20 21 // 再用Pants類裝飾Person22 $pants = new Pants($underwear);23 $pants->show(); // 我是學生JC,穿著DK,穿著褲子24 echo '<br>';25 26 // 再用Shirt類裝飾Person27 $shirt = new Shirt($pants);28 $shirt->show(); // 我是學生JC,穿著DK,穿著褲子,穿著襯衫29 echo '<br>';30 31 // 再用Glasses類裝飾Person32 $glasses = new Glasses($shirt);33 $glasses->show(); // 我是學生JC,穿著DK,穿著褲子,穿著襯衫,帶著眼鏡34 echo '<br>';
圖3 輸出結果截圖
Symfony2 EventDispatch 組件對裝飾者模式的應用
圖4 Symfony2 EventDispatch組件使用裝飾模式
圖5 Framework配置EventDispatcher
新聞熱點
疑難解答