装饰模式:给一个类添加一些额外的职责,并且在添加这些额外的职责时不会控制该类的执行逻辑。
UML类图:
组成部分:
抽象构件:原始的功能接口
具体构件:具体的原始功能类
装饰角色:持有具体构件类的对象,以便执行原有功能
具体装饰:具体扩展的功能在这里
1) 抽象构建角色(Component):给出一个抽象的接口,以规范准备接受附加责任的对象。相当于i/o流里面InputStream/OutputStream和Reader/Writer。
2) 具体的构建角色(ConcreteComponent):定义一个将要接受附加责任的类。相当于i/o里面的FileOutputStream和FileInputStream。
3) 装饰角色(Docorator):持有一个抽象构建(Component)角色的引用,并定义一个与抽象构件一致的接口。相当于i/o里面的FilerOutputStream和FilterInputStream。
4) 具体的装饰角色(ConcreteDecorator):负责给构建对象“贴上”附加的责任。相当于i/o流里面的BufferedOutputStream和BufferedInputStream以及DataOutputStream和DataInputSrtream。
下面看一个对开车功能拓展的实例(晚上+开车):抽象构件:
新建一个抽象汽车父类:
package car_package; public abstract class car_parent { // 汽车抽象父类 private String make_address; private int speed; public String getMake_address() { return make_address; } public void setMake_address(String make_address) { this.make_address = make_address; } public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } public abstract void print_face(); } |
然后新建一个奥迪汽车子类
package car_package; public class audi_sub extends car_parent { // 奥迪汽车子类 @Override public void print_face() { System.out.println("audi车默认的颜色为 黑色"); } } |
然后再新建一个装饰者父类:
package decorator_package; import car_package.car_parent; public abstract class decorator_parent extends car_parent { // 装饰者父类 protected car_parent car_parent_ref; public void setCar_parent_ref(car_parent car_parent_ref) { this.car_parent_ref = car_parent_ref; } @Override public void print_face() { car_parent_ref.print_face(); } } |
然后再新建装饰者子类:红色火焰装饰者类:
package decorator_package; public class decorator_audi_red extends decorator_parent { @Override public void print_face() { super.print_face(); System.out.println("给 奥迪 喷涂鸦 - 颜色为 红色火焰"); } } |
然后再新建装饰者子类:紫色霞光装饰者类:
package decorator_package; public class decorator_audi_purple extends decorator_parent { @Override public void print_face() { super.print_face(); System.out.println("给 奥迪 喷涂鸦 - 颜色为 紫色霞光"); } } |
新建一个运行类
package main_run; import car_package.audi_sub; import decorator_package.decorator_audi_purple; import decorator_package.decorator_audi_red; public class main_run { public static void main(String[] args) { audi_sub audi_sub_ref = new audi_sub(); audi_sub_ref.setMake_address("北京市朝阳区"); audi_sub_ref.setSpeed(200); decorator_audi_red decorator_audi_red_ref = new decorator_audi_red(); decorator_audi_red_ref.setCar_parent_ref(audi_sub_ref); decorator_audi_purple decorator_audi_purple_ref = new decorator_audi_purple(); decorator_audi_purple_ref.setCar_parent_ref(decorator_audi_red_ref); decorator_audi_purple_ref.print_face(); } } |
程序运行结果如下:
audi车默认的颜色为 黑色 给 奥迪 喷涂鸦 - 颜色为 红色火焰 给 奥迪 喷涂鸦 - 颜色为 紫色霞光 |
从程序结构中可以看到,完全符合了前面我们的要求:“灵活”,“顺序敏感”。