type
status
date
slug
summary
tags
category
icon
password
装饰器模式顾名思义在原有功能的基础上增加功能,不影响原有功能,是很符合设计模式中对修改封闭对拓展开放的原则的。
使用场景
- 需要扩展一个类的功能,或给一个类增加附加功能时
- 需要动态的给一个对象增加功能,这些功能可以再动态的撤销
- 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时
角色
- Component(抽象组件):接口或者抽象类,被装饰的最原始的对象。具体组件与抽象装饰角色的父类。
- ConcreteComponent(具体组件):实现抽象组件的接口。
- Decorator(抽象装饰角色):一般是抽象类,抽象组件的子类,同时持有一个被装饰者的引用,用来调用被装饰者的方法;同时可以给被装饰者增加新的职责。
- ConcreteDecorator(具体装饰类):抽象装饰角色的具体实现。
优缺点
优点:
- 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
- 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
- 装饰器模式完全遵守开闭原则
缺点:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。
结构
模板代码
看结构图可能不太清楚,还是看代码最直观,这里使用了小灰的代码,
车(抽象类Component),不同品牌的车(ConcreteComponent),现在想给不同品牌的车增加自动驾驶和飞行的功能,代码如下
可以发现面对需要多个扩展功能的时候,可以嵌套使用装饰器模式,非常灵活
使用实例ContextWrapper
java的io操作(InputStream\OutputStream)等相关的类都使用了该模式。在Android中Context、ContextImpl、ContextWrapper也使用了该模式。
Context
是一个抽象类,定义了很多关键的抽象方法,如启动Activity、发送广播、开启服务。Context
的具体实现类为ContextImpl
,它实现了Context
所有的抽象方法我们再看下
ContextWrapper
这个类可以看到,
ContextWrapper
持有Context
对象,并重写了一系列的抽象方法,很明显,这是典型的装饰模式的运用,ContextWrapper
充当具体的装饰者角色,对ContextImpl
进行功能增强。装饰器模式和代理模式的区别
这个是面试经常问的问题,代理模式中代理类也是持有被代理类的对象,他们的区别是:装饰模式是对所要装饰的对象的功能增强,而代理模式只是对代理的对象进行调用,不会对对象本身的功能有所增强。他们的界定确实有些模糊,它们的写法几乎是一样的,可以看代理模式那篇文章,有更详细的解释。
参考
- 作者:LuluNotion
- 链接:https://tangly1024.com/article/design-pattern-decorator
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章