- 定義
在不改變原有對象的基礎(chǔ)上,動態(tài)的給對象增加新的功能橙凳。提供了比繼承更加彈性的方案。
-
通用類圖
Decorator.png - 我對裝飾器模式的理解
- 組件
裝飾器模式中包括抽象組件(Component)锯玛、抽象裝飾者(Decorator)踏烙、具體組件(ConcreteComponent)、具體裝飾者(ConcreteDecorator)四種組件黔龟。
- 思想
- 定義一個頂層的抽象組件妇智,在抽象組件中定義一個組件中的屬性和方法。
- 讓裝飾器和具體的組件都去繼承這個抽象組件,使它們在同一繼承體系下氏身。在抽象裝飾器的構(gòu)造方法中傳入一個組件巍棱,從而可以獲取被裝飾的組件的實例。重寫抽象組件中定義的方法蛋欣。
- 實現(xiàn)具體的裝飾器航徙,重寫抽象組件中的方法,可以在具體邏輯處理之前或者之后增加功能陷虎。
- 一次擴展實現(xiàn)
背景:現(xiàn)有一個煎餅果子類到踏,只有基礎(chǔ)的煎餅果子該有的東西杠袱,并且已經(jīng)上線。現(xiàn)在想在不修改這個類的前提下進行功能擴展窝稿,比如加雞蛋楣富,加香腸。
/**
* 現(xiàn)有的煎餅果子類伴榔,不能添加任何功能纹蝴,只有名稱和基礎(chǔ)價格
*/
public class BaseBattercake{
public String getMsg() {
return "煎餅果子";
}
public int getPrice() {
return 5;
}
}
設(shè)計思路:
- 定義一個抽象裝飾器,繼承該類踪少。
- 定義具體的裝飾塘安,雞蛋裝飾和香腸裝飾。
//抽象裝飾器
public abstract class BattercakeDecorator extends BaseBattercake {
private BaseBattercake battercake;
public BattercakeDecorator(BaseBattercake battercake) {
this.battercake = battercake;
}
@Override
public String getMsg() {
return this.battercake.getMsg();
}
@Override
public int getPrice() {
return this.battercake.getPrice();
}
}
//雞蛋裝飾器
public class EggDecorator extends BattercakeDecorator {
public EggDecorator(BaseBattercake battercake) {
super(battercake);
}
@Override
public String getMsg() {
return super.getMsg() + "+ 一個雞蛋";
}
@Override
public int getPrice() {
return super.getPrice() + 1;
}
}
//香腸裝飾器
public class SausageDecorator extends BattercakeDecorator {
public SausageDecorator(BaseBattercake battercake) {
super(battercake);
}
@Override
public String getMsg() {
return super.getMsg() + "+ 一個香腸";
}
@Override
public int getPrice() {
return super.getPrice() + 2;
}
}
public class Test {
public static void main(String[] args) {
BaseBattercake battercake = new BaseBattercake();
System.out.println(battercake.getMsg() + battercake.getPrice());
BattercakeDecorator decorator = new EggDecorator(battercake);
decorator = new EggDecorator(decorator);
decorator = new SausageDecorator(decorator);
System.out.println(decorator.getMsg() +",¥"+ decorator.getPrice());
}
}
- 優(yōu)缺點
優(yōu)點:
- 裝飾器模式是繼承的有力補充援奢,比繼承更加靈活兼犯,在不改變原有功能的基礎(chǔ)上,進行功能的擴展萝究。
- 可以使用不同的裝飾類進行擴展免都,從而達到不同的效果。
- 使用裝飾器完全符合開閉原則帆竹。
缺點:
- 會出現(xiàn)更多的代碼和更多的類绕娘,增加系統(tǒng)的復(fù)雜度。
- 動態(tài)裝飾時栽连,多層裝飾更復(fù)雜险领。
- 與代理模式的對比
擴展面不同。裝飾器模式強調(diào)的是concreteComponent功能的擴展秒紧,主體對象是concreteComponent绢陌,著重類功能的變化。代理模式強調(diào)對代理過程的控制熔恢,Proxy完全掌握對RealSubject的控制脐湾,主體對象是Proxy。