Java设计模式之【装饰者模式】
Java设计模式之【装饰者模式】
装饰者模式出现的原因
要对类的功能进行增强,可以新建一个类继承这个类,这种方法可以解决问题,但如果增加的功能越来越多,那继承的层次就越来越深,造成继承冗余的问题
装饰者模式可以不用继承类而增强类的功能,原理是使用对象之间的关联关系取代类之间的继承关系
当然还可以使用代理模式来增强类的功能
装饰者模式中出现的角色
1、装饰器和被装饰者的抽象类
2、被装饰者(继承自装饰器和被装饰者的抽象类)
3、装饰器的抽象
4、装饰器的具体实现
下面以对门装锁再装猫眼的例子来具体介绍装饰者模式
类结构图
代码
Component
//装饰器和被装饰者的抽象类 public abstract class Component { //共有的抽象方法,也就是待装饰的方法 public abstract void show(); }
Door
//被装饰者,继承自被装饰者和装饰器的抽象类 public class Door extends Component { /** * 待装饰方法的具体实现 */ @Override public void show() { System.out.println("大家好我是门"); } }
ComponentDecorator
//装饰器的抽象 public abstract class ComponentDecorator extends Component { //被装饰者的引用,可以操作被装饰者 private Component component; //装饰者的构造器,用于初始化被装饰者对象 public ComponentDecorator(Component component) { this.component = component; } /** * 重写待装饰方法 */ @Override public void show() { component.show(); //调用被装饰者的待装饰方法 } }
LockDecorator
//装饰器的具体实现 public class LockDecorator extends ComponentDecorator { /** * 构造器 * @param component 被装饰者对象 */ public LockDecorator(Component component) { super(component); } /** * 重写待装饰方法 */ @Override public void show() { this.setLock(); //调用装饰方法 super.show(); //调用父类的待装饰方法,也就是被装饰者的待装饰方法 } /** * 装饰方法的实现 */ public void setLock(){ System.out.println("为组件加锁"); } }
EyeDecorator
//装饰器的具体实现 public class EyeDecorator extends ComponentDecorator { /** * 构造器 * @param component 被装饰者对象 */ public EyeDecorator(Component component) { super(component); } /** * 重写待装饰方法 */ @Override public void show() { this.setEye(); //调用装饰方法 super.show(); //调用父类的待装饰方法,也就是被装饰者的待装饰方法 } /** * 装饰方法的实现 */ public void setEye(){ System.out.println("为组件加猫眼"); } }
Customer(测试类)
public class Customer { public static void main(String[] args) { Component door, decorator1, decorator2; door = new Door(); decorator1 = new LockDecorator(door); //装饰door对象 decorator1.show(); System.out.println("------------------我是严肃的分割线------------------"); decorator2 = new EyeDecorator(decorator1); //装饰decorator1对象 decorator2.show(); } }
运行结果
为组件加锁 大家好我是门 ------------------我是严肃的分割线------------------ 为组件加猫眼 为组件加锁 大家好我是门
使用场合
1、需要为某个现有对象添加一个新功能时,可以考虑装饰者模式或代理模式
2、某个对象的功能经常发生变化或经常需要动态添加功能时
JDK中的InputStream就是经典的装饰者模式,有兴趣的小伙伴可以研究下源码