说明
装饰器模式(Decorator)是一种结构型模式,顾名思义,就是对已经存在的某些类进行装饰,以此来扩展一些功能。
应用场景
在不想更改已存在类的核心功能的情况下,想要扩展该类的功能
模式特征
角色 | 说明 | 举栗 |
---|---|---|
Component | 统一接口,也是装饰类和被装饰类的基本类型 | OperateSystem |
ConcreteComponent | 具体实现类,也是被装饰类,他本身是个具有一些功能的完整的类 | Windows |
Decorator | 装饰类,实现了Component接口的同时还在内部维护了一个ConcreteComponent的实例,并可以通过构造函数初始化。而Decorator本身,通常采用默认实现,他的存在仅仅是一个声明:我要生产出一些用于装饰的子类了。而其子类才是赋有具体装饰效果的装饰产品类 | Decorator |
ConcreteDecorator | 具体的装饰产品类,每一种装饰产品都具有特定的装饰效果。可以通过构造器声明装饰哪种类型的ConcreteComponent,从而对其进行装饰 | HuaweiDecorator、LevonoDecorator |
UML
代码实现
- OperateSystem 操作系统
public interface OperateSystem {
void startup();
}
- Windows 具体系统
public class Windows implements OperateSystem {
@Override
public void startup() {
System.out.println("Windows系统启动中...");
}
}
- Decorator 装饰器
public class Decorator implements OperateSystem{
protected OperateSystem operateSystem;
public Decorator(OperateSystem operateSystem) {
this.operateSystem = operateSystem;
}
public void startup(){
operateSystem.startup();
}
}
- HuaweiDecorator 具体装饰器一
public class HuaweiDecorator extends Decorator {
public HuaweiDecorator(OperateSystem operateSystem) {
super(operateSystem);
}
@Override
public void startup() {
System.out.println("华为电脑");
super.startup();
}
}
- LevonoDecorator 具体装饰器二
public class LevonoDecorator extends Decorator {
public LevonoDecorator(OperateSystem operateSystem) {
super(operateSystem);
}
@Override
public void startup() {
System.out.println("联想电脑");
super.startup();
}
}
- 客户端测试代码
public class Client {
public static void main(String[] args) {
//华为装饰器
Decorator decorator = new HuaweiDecorator(new Windows());
decorator.startup();
//联想装饰器
Decorator decorator1 = new LevonoDecorator(new Windows());
decorator1.startup();
}
}
- 结果
华为电脑
Windows系统启动中...
联想电脑
Windows系统启动中...
模式对比
很多刚刚接触设计模式的同学,很容易将装饰器模式和静态代理模式混淆,下面简单说说他们之间的区别,需要用心体会。
- 对装饰器模式来说,装饰者和被装饰者都实现一个接口。对代理模式来说,代理类和真实处理的类也都实现同一个接口。此外,不论我们使用哪一个模式,都可以很容易地在真实对象的方法前面或者后面加上自定义的方法.
- 装饰器模式关注于在一个对象上动态地添加方法,而代理模式关注于控制对对象的访问。换句话说,用代理模式,代理类可以对它的客户隐藏一个对象的具体信息。因此当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例;当使用装饰器模式的时候,我们通常的做法是将原始对象作为一个参数传给装饰器的构造器,简单的说,就是调用者主动将一个对象传入装饰器的构造器,来主动装饰它,调用者知道原始对象的存在。