【设计模式】(十二)–结构型模式–装饰器模式
装饰器模式定义
Attach additional responsibilities to an object dynamically keeping the same interface Decorators provide a flexible alternative to subclassing for extending funcionality.
意思是:动态的给一个对象添加一些额外的职责。就增加功能来看,装饰器模式比生成子类更加灵活。
装饰器模式一般有4个角色
- 抽象类 功能抽象接口,定义功能约束
- 被装饰的原始类 抽象类的实现,在装饰器模式中将被装饰
- 装饰基类 持有被装饰原始类的对象,并且继承了抽象
- 具体装饰类 实现了装饰基类,对被撞死的原始类进行装饰
装饰器模式优点
- 装饰类和被装饰类可以独立发展,不会相互耦合。
- 装饰器模式是继承的一个替代模式
- 装饰器模式可以动态扩展一个实现类的功能。
但是装饰器模式的实际上从抽象类到具体装饰类已经多次继承实现,在多层的装饰上会更复杂。
装饰器模式的使用场景
- 1、扩展一个类的功能。 或者增加一个类的附加功能
- 2、动态增加功能,动态撤销。
与代理模式对比1
让别人帮助你做你并不关心的事情,叫代理模式。为让自己的能力增强,使得增强后的自己能够使用更多的方法,拓展在自己基础之上的功能的,叫装饰器模式。
对装饰器模式来说,装饰者(decorator)和被装饰者(decoratee)都实现同一个 接口。对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口。他们之间的边界确实比较模糊,两者都是对类的方法进行扩展,具体区别如下:
1、装饰器模式强调的是增强自身,在被装饰之后你能够在被增强的类上使用增强后的功能。增强后你还是你,只不过能力更强了而已;代理模式强调要让别人帮你去做一些本身与你业务没有太多关系的职责(记录日志、设置缓存)。代理模式是为了实现对象的控制,因为被代理的对象往往难以直接获得或者是其内部不想暴露出来。
2、装饰模式是以对客户端透明的方式扩展对象的功能,是继承方案的一个替代方案;代理模式则是给一个对象提供一个代理对象,并由代理对象来控制对原有对象的引用;
3、装饰模式是为装饰的对象增强功能;而代理模式对代理的对象施加控制,但不对对象本身的功能进行增强;
接上篇,代理模式。在点火开火时,使用代理模式开煤气,关煤气,并没有增强煤气灶的功能。接下来简单的实现装饰器模式,将给煤气灶增强,加上烤架,让煤气灶还能给烤肉。这不春节太馋的日常吗?
简单的实现
类图
实现
public class ConcreteCookerDecorator extends CookerDecorator {
public ConcreteCookerDecorator(Cooker cooker) {
super(cooker);
}
private void barbecue() {
System.out.println("各就各位,烤肉走起。");
}
private void addGridiron() {
System.out.println("上烤架!");
}
private void removeGridiron() {
System.out.println("撤烤架!");
}
@Override
public void start() {
super.start();
this.addGridiron();
this.barbecue();
}
@Override
public void stop() {
super.stop();
this.removeGridiron();
}
public static void main(String[] args) {
Cooker gasCooker = new GasCooker();
CookerDecorator cookerDecorator = new ConcreteCookerDecorator(gasCooker);
cookerDecorator.start();
cookerDecorator.stop();
}
}
public abstract class CookerDecorator implements Cooker {
private Cooker cooker = null;
public CookerDecorator(Cooker cooker) {
this.cooker = cooker;
}
@Override
public void start() {
cooker.start();
}
@Override
public void stop() {
cooker.stop();
}
}
public class GasCooker implements Cooker {
@Override
public void start() {
System.out.println("煤气灶点火成功!!");
}
@Override
public void stop() {
System.out.println("结束,关火!");
}
}
public interface Cooker {
void start();
void stop();
}
结果
代理模式和装饰器模式的区别(https://zhuanlan.zhihu.com/p/97499017) ↩︎