1 概述
装饰者(Decorator)模式是一种常见的设计模式,其旨在不改变原有类和不使用继承的情况下,动态地扩展一个类的功能。装饰者模式的实现方式是定义一个包装类(Wrapper)或者叫装饰类,该类维护一个被装饰类的引用。在调用功能函数时,装饰类除了调用被装饰类的方法外,还调用增强的功能,从而达到动态扩展类功能的作用。
2 实现方式
2.1 实现过程
装饰者模式的核心是装饰类和被装饰类两个类,这两个类需要继承同一个父类或者实现通过接口,表示这两个类属于同一个类体系中。这里举个简单的例子进行说明,具体参考下列代码:
public class DecoratorDemo {
public static void main(String[] args) {
SmartPhone smartPhone = new SmartPhone(new MobilePhone());
smartPhone.function();
}
}
interface Phone {
void function();
}
class MobilePhone implements Phone {
@Override
public void function() {
System.out.println("call and send message");
}
}
class SmartPhone implements Phone {
private Phone phone;
public SmartPhone(Phone phone) {
this.phone = phone;
}
@Override
public void function() {
phone.function();
wechat();
}
private void wechat() {
System.out.println("chat with wechat");
}
}
首先有个共同的接口Phone(不用IPhone是避免误解成苹果手机),其中有个需要实现的方法function,表示手机的功能。被装饰类MobilePhone,实现了function函数,表示普通手机只有打电话和发短信的功能。装饰类SmartPhone(智能机)维护了一个Phone型接口的引用指向被装饰的对象,在function方法的实现中,首先调用了被装饰对象的function函数,除此之外还调用了函数wechat,表示智能机还有聊微信的增强功能。
2.2 UML类图
装饰者设计模式的UML类图表示比较简单,如下图所示:
3 总结
装饰者模式在扩展模块功能时比继承的方案更加具有弹性,在JDK中装饰者模式的经典实践是IO相关类的设计。装饰者模式和代理模式有点类似,它们的不同更多的体现在语义上的不同。前者主要是对被装饰的对象提供增强和扩展的功能,而后者更多的是强调代理对象对被代理对象的控制,例如经典的Spring AOP的实现。