Java-装饰者-设计模式(六)
说明
装饰者模式可以实现对原类进行动态的功能扩展,装饰者与被装饰者共同继承一个超类或实现一个接口,并且装饰者要拥有被装饰者的对象实例,具体代码如下。
UML
代码
以为电脑扩展内存、硬盘、软件为例,计算价格。
顶级父类,是一个没有规定类型的电脑
/** * @author ctl * @date 2021/1/16 * 顶级父类 */ public abstract class Computer { protected String name; public String getName() { return name; } public abstract int getPrice(); }
要扩展的类,是一台macbook,原价为9999
/** * @author ctl * @date 2021/1/16 * 要扩展的类 */ public class MacBook extends Computer { public MacBook() { name = "MacBook"; } @Override public int getPrice() { return 9999; } }
要扩展的类都继承这个抽象父类
/** * @author ctl * @date 2021/1/16 * 扩展类,给后面具体扩展类做抽象父类 */ public abstract class Adder extends Computer { @Override abstract public String getName(); }
内存扩展类,价格1500
/** * @author ctl * @date 2021/1/16 * 加内存 要1500 */ public class Memory extends Adder { Computer computer; public Memory(Computer computer) { this.computer = computer; } @Override public String getName() { return computer.getName() + " 加内存"; } @Override public int getPrice() { return computer.getPrice() + 1500; } }
软件扩展类,价格1000
/** * @author ctl * @date 2021/1/16 * 软件扩展类 价格1000 */ public class SoftWare extends Adder { Computer computer; public SoftWare(Computer computer) { this.computer = computer; } @Override public String getName() { return computer.getName() + " 装软件"; } @Override public int getPrice() { return computer.getPrice() + 1000; } }
硬盘扩展类,价格3000
/** * @author ctl * @date 2021/1/16 * 硬盘 价格3000 */ public class Ssd extends Adder { Computer computer; public Ssd(Computer computer) { this.computer = computer; } @Override public String getName() { return computer.getName() + " 加硬盘"; } @Override public int getPrice() { return computer.getPrice() + 3000; } }
测试类
/** * @author ctl * @date 2021/1/16 */ public class DecoratorMain { public static void main(String[] args) { // 一步一步扩展 Computer computer = new MacBook(); System.out.println(computer.getName() + " 价格:" + computer.getPrice()); Memory memory = new Memory(computer); System.out.println(memory.getName() + " 价格:" + memory.getPrice()); SoftWare softWare = new SoftWare(memory); System.out.println(softWare.getName() + " 价格:" + softWare.getPrice()); Ssd ssd = new Ssd(softWare); System.out.println(ssd.getName() + " 价格:" + ssd.getPrice()); // 分割线 System.out.println("---------------------------"); // 一步到位 Computer computer1 = new Memory(new SoftWare(new Ssd(new MacBook()))); System.out.println(computer1.getName() + " 价格:" + computer1.getPrice()); } }
结果如下 可以一步一步扩展计算价格,也可以一步扩展多个,再计算价格。
总结
这种模式的要点就在于继承关系,并且装饰者要拥有被装饰者的实例。其实也是用到了一些委托的概念,一级一级向上委托计算并返回结果。Java的IO中大量用到了这种模式。