簡介 裝飾器模式又叫做裝飾者模式,屬於結構型的設計模式。 指的是在不改變原類文件和使用繼承的情況下動態擴展這個對象的功能,從而修飾源數據。 組成: 抽象構件(Component)角色:定義一個抽象介面以規範準備接收附加責任的對象。 具體構件(ConcreteComponent)角色:實現抽象構件,通 ...
簡介
裝飾器模式又叫做裝飾者模式,屬於結構型的設計模式。
指的是在不改變原類文件和使用繼承的情況下動態擴展這個對象的功能,從而修飾源數據。
組成:
抽象構件(Component)角色:定義一個抽象介面以規範準備接收附加責任的對象。
具體構件(ConcreteComponent)角色:實現抽象構件,通過裝飾角色為其添加一些職責。
抽象裝飾(Decorator)角色:繼承抽象構件,並包含具體構件的實例,可以通過其子類擴展具體構件的功能。
具體裝飾(ConcreteDecorator)角色:實現抽象裝飾的相關方法,並給具體構件對象添加附加的責任。
適用場景
適用於多繼承,且不改變原數據的場景。當然,是可以通過繼承的方式來達到同樣的效果,但是繼承耦合度很大。
優點
- 裝飾器模式是繼承的一種替代方式,通過組合的方式完成繼承的功能,降低繼承的強關聯耦合。
- 降低類間的耦合。被裝飾類和裝飾類都可以獨立發展,不會相互影響。
- 符合開閉原則。
- 繼承是靜態地給類增加功能,而裝飾模式則是動態地增加功能,更靈活。
缺點
裝飾器模式會增加許多子類,增加程式複雜性。
其它
為什麼不用繼承?
是可以通過繼承的方式裝飾原有的類,但是一旦繼承關係確認起來,想要再次擴展,就需要更多的子類,由於繼承是強依賴關係,那麼一定會產生很多的耦合。
為此產生了裝飾器模式,有更好的橫向擴展方案。
代碼
//定義一個裝飾器模式的契約
interface RenderInterface {
public function renderData();
}
//按照RenderInterface契約,實現一個傳遞數據的方法
class Init implements RenderInterface {
private $data;
public function __construct($data) {
$this->data = $data;
}
public function renderData() {
return $this->data;
}
}
/**
裝飾者必須實現渲染介面類 RenderInterface 契約,這是該設計模式的關鍵點。否則,這將不是一個裝飾者而只是一個自欺欺人的包裝。
創建抽象類 RendererDecorator (渲染器裝飾者)實現渲染介面。
*/
abstract class RendererDecorator implements RenderInterface {
protected $object;
public function __construct(RenderInterface $object) {
$this->object = $object;
}
}
//按照RenderInterface契約,實現一個自增的類
class Increment extends RendererDecorator {
public function renderData() {
return $this->object->renderData() + 1;
}
}
//按照RenderInterface契約,實現一個自減的類
class Decrement extends RendererDecorator {
public function renderData() {
return $this->object->renderData() - 1;
}
}
//調用端=====================================================
$init = new Init(1);
echo (new Increment($init))->renderData();
echo (new Decrement($init))->renderData();
echo (new Init(1))->renderData();