今天通過網課學習了裝飾者模式,總結如下:
1.四部分:
抽象組件conponent:給出一個抽象接口,以規範準接接受附加責任的對象(裝飾基類:飲料)
被裝飾者concreteconponent:conponent的具體實現,也就是裝飾的對象(具體對象:如豆漿,包括 初始價格,初始原料)
裝飾者組件decorator:裝飾具體組件對象,附加職責(操作:如加錢,加料操作)
具體裝飾concreteDecorator:負責給構建對象裝飾附加功能(功能:加錢3.5,加料紅糖)
實際應用,可以首先先找到需要被改造的類,就是“被裝飾者”,然後尋找被裝飾者繼承的父類,就是“抽象組件”,然後再繼承抽象組件構造“裝飾者組件”,選擇要被重造的方法。
最後在一一對方法進行實現,即具體裝飾。然後裝配。
優點:
- 裝飾者模式比繼承有更好的靈活性
- 裝飾者模式是動態的,繼承是靜態的
- 裝飾者模式可以用不同的裝飾類進行組合,可以產生許多中不同的行爲
缺點:
- 會產生很多的小對象,佔用內存
- 組合方式多,容易出錯
代碼演示:
public interface Drink {
// 抽象組件
//價格
public double money();
//品種描述
public String desc();
}
public class Soya implements Drink {
// 被裝飾者
@Override
public double money() {
return 5;
}
@Override
public String desc() {
return "純豆漿";
}
}
public abstract class Decorator implements Drink {
// 裝飾器
// 1. 抽象類
// 2. 實現抽象組件的接口
// 3. 持有抽象接口的引用
// 定義私有飲品的接口引用
private Drink drink;
public Decorator(Drink drink) {
this.drink = drink;
}
@Override
public double money() {
return drink.money();
}
@Override
public String desc() {
return drink.desc();
}
}
public class RedBean1 extends Decorator {
// 具體裝飾1
public RedBean1(Drink drink) {
super(drink);
}
// 重寫money
@Override
public double money() {
return super.money() + 3.5;
}
// 重寫描述
@Override
public String desc() {
return super.desc() + "+紅豆1";
}
}
public class RedBean2 extends Decorator {
// 具體裝飾1
public RedBean2(Drink drink) {
super(drink);
}
// 重寫money
@Override
public double money() {
return super.money() + 4;
}
// 重寫描述
@Override
public String desc() {
return super.desc() + "+紅豆2";
}
}
public class Test {
// 測試
public static void main(String[] args) {
// 開始搭配
// 創建豆漿對象
Drink soya = new Soya();
System.out.println(soya.desc() + “===” + soya.money());
// 加紅糖1
Drink readbean1 = new RedBean1(soya);
System.out.println(readbean1.desc() + "===" + readbean1.money());
// 加紅糖2
Drink readbean2 = new RedBean1(readbean1);
System.out.println(readbean2.desc() + "===" + readbean2.money());
}