一天一個設計模式---裝飾者模式
阿新 • • 發佈:2019-01-27
優點:它可以動態為物件新增功能。
場景:我們希望為某個物件而不是整個類新增一些功能。
一、角色及作用
裝飾者和被裝飾者擁有相同的元件介面。被裝飾者是系統的核心元件,完成特定功能。裝飾者則可以在被裝飾者的方法前後,加上特定的前置處理和後置處理,增強被裝飾者的功能(怎麼和代理模式好像!_!,一臉懵逼)
角色 | 作用 |
---|---|
元件介面 | 為裝飾者和被裝飾者的超類或介面。定義被裝飾者的核心功能,以及裝飾者需要加強的功能 |
具體元件(被裝飾者) | 實現元件介面的的核心方法,完成具體業務邏輯 |
裝飾者 | 實現元件介面,持有一個被裝飾物件 |
具體裝飾者 | 具體實現裝飾的業務邏輯。各個具體裝飾者是可以相互疊加的 |
二、裝飾者模式
場景:奶茶哥哥的奶茶店開張了,我們推出了兩種產品—奶茶和茶葉茶。我們的飲料需要實現自己的描述和自己的價格。
// 飲料的基類(元件介面)
public interface Beverage {
public String getDescription();
public double cost();
}
// 奶茶(被裝飾者)
public class Milk implements Beverage {
@Override
public double cost() {
return .56;
}
@Override
public String getDescription() {
return "Milk";
}
}
// 茶葉茶(被裝飾者)
public class Tea implements Beverage {
@Override
public double cost() {
return 1.44;
}
@Override
public String getDescription() {
return "Tea";
}
}
奶茶店開張後,我們的飲料很暢銷,但是沒有新的產品是無法滿足客戶的。於是,我們研製了調料,讓我們的飲料喝起來味道更好。
// 調料的基類(裝飾者)
public abstract class CondimentDecorator implements Beverage {
Beverage beverage;
public CondimentDecorator(Beverage beberage) {
this.beverage = beberage;
}
}
// 抹茶粉(具體裝飾者)
public class Matcha extends CondimentDecorator {
public Matcha(Beverage beberage) {
super(beberage);
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Matcha";
}
@Override
public double cost() {
return .5 + beverage.cost();
}
}
// 珍珠(具體裝飾者)
public class Pearl extends CondimentDecorator {
public Pearl(Beverage beberage) {
super(beberage);
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Pearl";
}
@Override
public double cost() {
return .2 + beverage.cost();
}
}
現在我們提供奶茶的方法如下:
public static void main(String[] args) {
Beverage be = new Tea();
System.out.println(be.getDescription() + "---" + be.cost());
Beverage b2 = new Pearl(new Milk());
System.out.println(b2.getDescription() + "---" + b2.cost());
b2 = new Matcha(b2);
System.out.println(b2.getDescription() + "---" + b2.cost());
}
輸出如下:
Tea---1.44
Milk,Pearl---0.76
Milk,Pearl,Matcha---1.26
可見,我們根據所需要的飲料和調料,奶茶哥哥就提供對應的飲料和價格資料。
三、裝飾者模式和代理模式的區別
首先,這兩個模式真心在實現上太像了,都是對業務處理的前後增加前置後置的實現。網上找了很多人對這兩者的理解,這裡總結下我的看法。
裝飾模式:
- 以對客戶端透明的方式擴充套件物件的功能
- 可以說是繼承關係的一個替代方案
- 使用者更關心裝飾後的功能
比如上面的奶茶,使用者希望得到的是—奶茶+珍珠+抹茶,以及他們的總價
代理模式:
- 代理模式對代理的物件施加控制,並不提供物件本身的增強功能
- 使用者通過代理來訪問目標的功能,使用者關心的是原始功能都有什麼功能,而對於代理的時候的處理卻不知道
比如在代理模式中提到的成龍大哥和經紀人的例子,我們更加關心的應該是成龍大哥演戲,而不是經紀人對業務的處理。