PHP設計模式(六)—裝飾器模式(Decorator Pattern)
裝飾器模式(Decorator Pattern): 允許向一個已有的物件新增新的功能或部分內容,同時又不改變其結構。屬於結構型模式,它是作為現有的類的一個包裝。
(一)為什麼需要裝飾器模式:
1,我們要對一個已有的物件新增新功能,又不想修改它原來的結構。
2,使用子類繼承的方法去實現新增新功能,會不可避免地出現子類過多,繼承鏈很長的情況。而且不少書籍都規勸我們竭力保持一個物件的父與子關係不超過3個。
3,裝飾器模式,可以提供對物件內容快速非侵入式地修改。
(二)裝飾器模式UML圖
(三)簡單例項
如果有一個遊戲角色,他原來就是預設穿一件長衫。現在遊戲改進了,覺得這個角色,除了穿一件長衫前,還可以在裡面穿一件袍子,或是一件球衣。在外面穿一套盔甲或是宇航服。
<?php
/*遊戲原來的角色類
class Person{
public function clothes(){
echo "長衫".PHP_EOL;
}
}
*/
//裝飾器介面
interface Decorator
{
public function beforeDraw();
public function afterDraw();
}
//具體裝飾器1-宇航員裝飾
class AstronautDecorator implements Decorator
{
public function beforeDraw()
{
echo "穿上T恤".PHP_EOL;
}
function afterDraw()
{
echo "穿上宇航服".PHP_EOL;
echo "穿戴完畢".PHP_EOL;
}
}
//具體裝飾器2-警察裝飾
class PoliceDecorator implements Decorator{
public function beforeDraw()
{
echo "穿上警服".PHP_EOL;
}
function afterDraw()
{
echo "穿上防彈衣".PHP_EOL;
echo "穿戴完畢".PHP_EOL;
}
}
//被裝飾者
class Person{
protected $decorators = array(); //存放裝飾器
//新增裝飾器
public function addDecorator(Decorator $decorator)
{
$this->decorators[] = $decorator;
}
//所有裝飾器的穿長衫前方法呼叫
public function beforeDraw()
{
foreach($this->decorators as $decorator)
{
$decorator->beforeDraw();
}
}
//所有裝飾器的穿長衫後方法呼叫
public function afterDraw()
{
$decorators = array_reverse($this->decorators);
foreach($decorators as $decorator)
{
$decorator->afterDraw();
}
}
//裝飾方法
public function clothes(){
$this->beforeDraw();
echo "穿上長衫".PHP_EOL;
$this->afterDraw();
}
}
//警察裝飾
$police = new Person;
$police->addDecorator(new PoliceDecorator);
$police->clothes();
//宇航員裝飾
$astronaut = new Person;
$astronaut->addDecorator(new AstronautDecorator);
$astronaut->clothes();
//混搭風
$madman = new Person;
$madman->addDecorator(new PoliceDecorator);
$madman->addDecorator(new AstronautDecorator);
$madman->clothes();
當然,上面的程式碼沒有嚴格地按照UML圖,這是因為當被裝飾者只有一個時,那 Component也就是ConcreteComponent。同理,如果,只有一個裝飾器,那也沒必要實現一個implment介面。
如果我們有兩個不同的被裝飾者,那當然就應該抽象出一個Component,讓這兩個被裝飾者去繼承它。也許,那繼承不是又來了嗎。既然外面都用到繼承,直接把裝飾器的方法放到繼承裡面不就行了。
可是你想,如果,直接通過繼承的話,那裝飾過的被裝飾者就應該繼承自被裝飾者,而且被裝飾者因為裝飾的不同還要有很多不同型別的子類。而使用裝飾者模式的話,繼承鏈縮短了,而且不同的裝飾型別還可以動態增加。
相關文章
- 設計模式之裝飾器模式(decorator pattern)設計模式
- 設計模式--裝飾模式(Decorator Pattern)設計模式
- 設計模式-裝飾模式(Decorator Pattern)設計模式
- C#設計模式-裝飾器模式(Decorator Pattern)C#設計模式
- PHP設計模式- Decorator 裝飾器模式PHP設計模式
- PHP設計模式之裝飾器模式(Decorator)PHP設計模式
- 裝飾模式 (Decorator Pattern)模式
- Decorator裝飾設計模式設計模式
- 設計模式(六):裝飾器模式設計模式
- 裝飾器模式(Decorator)模式
- 前端常用設計模式(1)--裝飾器(decorator)前端設計模式
- 設計模式----裝飾器模式設計模式
- 設計模式-裝飾器模式設計模式
- [設計模式] 裝飾器模式設計模式
- PHP設計模式之裝飾者模式PHP設計模式
- Python設計模式-裝飾器模式Python設計模式
- 設計模式之-裝飾器模式設計模式
- 設計模式(八)裝飾器模式設計模式
- java設計模式--裝飾器模式Java設計模式
- 設計模式之【裝飾器模式】設計模式
- 設計模式中的俄羅斯套娃:裝飾者(Decorator)模式設計模式
- Go 設計模式之裝飾器模式Go設計模式
- Java 設計模式(五)《裝飾器模式》Java設計模式
- java設計模式之裝飾器模式Java設計模式
- Java設計模式系列-裝飾器模式Java設計模式
- 設計模式——裝飾模式設計模式
- 設計模式-裝飾模式設計模式
- Java學設計模式之裝飾器模式Java設計模式
- 設計模式專題(七)裝飾器模式設計模式
- 【趣味設計模式系列】之【裝飾器模式】設計模式
- 23種設計模式(三)--裝飾器模式設計模式
- PHP設計模式(一)—單例模式(Singleton Pattern)PHP設計模式單例
- c++設計模式-裝飾器模式和代理模式C++設計模式
- 設計模式 #4 (裝飾器模式、介面卡模式)設計模式
- 設計模式——裝飾者模式設計模式
- 設計模式-裝飾者模式設計模式
- [設計模式]裝飾者模式設計模式
- 09 結構型模式之裝飾者模式(decorator)模式
- 裝飾器設計模式 - Gene Zeiniss設計模式