1. 模式简介
在不改变原有对象的基础之上,将新功能附加到原有对象上,提供了比继承更有弹性的解决方案(扩展原有对象的功能),属于结构型设计模式
。
2. 示例代码
这回咱们就土豪一把,模拟购买 2019 款 MacBook Pro 16 寸,来演示装饰者模式的逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
public interface MacBookPro {
String getComboName();
String getHardDisk();
String getMemory();
Double getPrice(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
@AllArgsConstructor public abstract class ComboDecorator implements MacBookPro { private MacBookPro macBookPro;
@Override public String getComboName() { return this.macBookPro.getComboName(); }
@Override public String getHardDisk() { return this.macBookPro.getHardDisk(); }
@Override public String getMemory() { return this.macBookPro.getMemory(); }
@Override public Double getPrice() { return this.macBookPro.getPrice(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
public class BaseMacBookProCombo implements MacBookPro {
@Override public String getComboName() { return "基础套餐"; }
@Override public String getHardDisk() { return "1T 固态硬盘"; }
@Override public String getMemory() { return "16GB 2666MHz DDR4 内存"; }
@Override public Double getPrice() { return 22199d; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
public class MemoryCombo extends ComboDecorator { public MemoryCombo(MacBookPro macBookPro) { super(macBookPro); }
@Override public String getComboName() { return super.getComboName() + " + 升级内存"; }
@Override public String getMemory() { return super.getMemory() + " + 16G 内存"; }
@Override public Double getPrice() { return super.getPrice() + 2936; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
public class HardDiskCombo extends ComboDecorator { public HardDiskCombo(MacBookPro macBookPro) { super(macBookPro); }
@Override public String getComboName() { return super.getComboName() + " + 升级硬盘"; }
@Override public String getHardDisk() { return super.getHardDisk() + " + 1TB 固态硬盘"; }
@Override public Double getPrice() { return super.getPrice() + 2936; } }
|
- 测试类,我们需要购买一台 2T 固态硬盘 64G 内存的 MacBook Pro
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
public class PatternTest { public static void main(String[] args) { MacBookPro macBookPro = new BaseMacBookProCombo(); printInfo(macBookPro);
macBookPro = new MemoryCombo(macBookPro); macBookPro = new MemoryCombo(macBookPro); macBookPro = new MemoryCombo(macBookPro); printInfo(macBookPro);
macBookPro = new HardDiskCombo(macBookPro); printInfo(macBookPro); }
private static void printInfo(MacBookPro macBookPro) { System.out.println("当前套餐: " + macBookPro.getComboName()); System.out.println("内存: " + macBookPro.getMemory()); System.out.println("硬盘: " + macBookPro.getHardDisk()); System.out.println("总价为: " + macBookPro.getPrice() + " 元"); System.out.println("\n======================================\n"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 当前套餐: 基础套餐 内存: 16GB 2666MHz DDR4 内存 硬盘: 1T 固态硬盘 总价为: 22199.0 元
======================================
当前套餐: 基础套餐 + 升级内存 + 升级内存 + 升级内存 内存: 16GB 2666MHz DDR4 内存 + 16G 内存 + 16G 内存 + 16G 内存 硬盘: 1T 固态硬盘 总价为: 31007.0 元
======================================
当前套餐: 基础套餐 + 升级内存 + 升级内存 + 升级内存 + 升级硬盘 内存: 16GB 2666MHz DDR4 内存 + 16G 内存 + 16G 内存 + 16G 内存 硬盘: 1T 固态硬盘 + 1TB 固态硬盘 总价为: 33943.0 元
======================================
|
3. UML 图例
4. 应用
5. 场景
- 用于扩展一个类的功能。
- 给一个类添加附加职责。
- 动态的给一个对象添加功能,这些功能可以再动态的撤销。
6. 优缺点
优点: 1、装饰者是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象 扩展功能,即插即用。 2、通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。 3、装饰者完全遵守开闭原则。
缺点: 1、会出现更多的代码,更多的类,增加程序复杂性。 2、动态装饰时,多层装饰时会更复杂。
7. 完整代码地址
https://github.com/xkcoding/design-pattern/tree/master/src/main/java/com/xkcoding/design/pattern/structural/decorator