裝飾者模式(Decorator Pattern)允許在不改變原對象前提下,動態、透明地為單個對象添加職責。相比繼承生成子類,組合方式更靈活,避免「類爆炸」。
適用場景:
| 角色 | 火鍋對應 | 代碼體現 |
|---|---|---|
| Component(抽象被裝飾者) | 鍋底接口 | GuoDi 接口 |
| ConcreteComponent(具體被裝飾者) | 鴛鴦鍋底、大龍燚原味鍋底 | YuanYang、DaLongYan 實現類 |
| Decorator(抽象裝飾者) | 配菜抽象基類 | PeiCai 抽象類,持有 GuoDi 引用 |
| ConcreteDecorator(具體裝飾者) | 麻辣牛肉、大刀毛肚、天味香腸… | MaLaNiuRou、MaoDu 等具體類 |
public interface GuoDi {
float cost(); // 價格
String name(); // 名稱
}
public class YuanYang implements GuoDi {
public float cost() { return 48.0f; }
public String name() { return "鴛鴦鍋底"; }
}
public class DaLongYan implements GuoDi {
public float cost() { return 59.0f; }
public String name() { return "大龍燚火鍋原味鍋底"; }
}
public abstract class PeiCai implements GuoDi {
protected GuoDi guodi;
public PeiCai(GuoDi guodi) { this.guodi = guodi; }
public float cost() { return guodi.cost(); }
public String name() { return guodi.name(); }
}
public class MaLaNiuRou extends PeiCai {
public MaLaNiuRou(GuoDi guodi) { super(guodi); }
public float cost() { return super.cost() + 46f; }
public String name() { return super.name() + "+麻辣牛肉"; }
}
public class MaoDu extends PeiCai {
public MaoDu(GuoDi guodi) { super(guodi); }
public float cost() { return super.cost() + 30f; }
public String name() { return super.name() + "+大刀毛肚"; }
}
public class Test {
public static void main(String[] args) {
GuoDi guodi = new DaLongYan(); // 1. 點鍋底
GuoDi y = new MaLaNiuRou(guodi); // 2. 加麻辣牛肉
GuoDi x = new MaoDu(y); // 3. 再加大刀毛肚
System.out.println("一共點了 " + x.name() + ", 共消費 " + x.cost());
}
}
一共點了 大龍燚火鍋原味鍋底+麻辣牛肉+大刀毛肚, 共消費 135.0
