装饰者(Decorator)模式
参考:廖雪峰的博客
介绍
类型:结构型模式。
定义:在不改变原有对象的基础上,将功能附加到对象上。
优势:提供了比集成更有弹性的替代方案(扩展原有对象功能)。
整体UML类图
代码中使用
1 | //先定义一个“具体构件”实例 |
这样写的优势
小伙伴们可能会疑惑,我所有需要用到的实体类直接继承Component接口不就好了,何必如此麻烦?
答:组合使用,更灵活。
现有业务场景如下:
- Component中定义的
operation()
方法为业务核心功能,所有继承它的类都必须实现。
- 现有一些附加功能A、附加功能B 和 附加功能C。
好了,现在你要开始用这个Component了。
你完全可以定义三个类继承Component各自实现其附加功能ABC,需要用的时候直接使用。至此一切都没问题,直到领导给你提了第三个需求:
- 需要附加功能AB。
这个时候你应该不太愿意会又写一个类,来继承Component,以实现附加功能AB。因为你知道,领导的下一个需求将会是BC(或AC)。
这里只有三个附加功能,如果附加功能多了的话,排列组合起来将会是个爆炸数字。想到这里,继承的方式已经不可取了。
现在你再回过头来看上面☝的使用代码。
文章开头写的 提供了比集成更有弹性的替代方案(扩展原有对象功能) 正是这个意思。
实际中的运用
其中,InputStream既是Component,也是ConcreteComponent。通过传入不同的InputStream对象,可以实现不同的功能。
要想实现FilterInputStream,可以:
1 | // 创建原始的数据源: |
想加上缓冲功能,可以:
1 | // 增加缓冲功能: |
再加个CCache(缓存?)功能,可以:
1 | //继续增加功能 |
如图所示,Application
、Activity
和Service
这三个类虽然分别各种承担着不同的作用,但它们都属于Context的一种,而它们具体Context的功能则是由ContextImpl
类去实现的,Android将很多调用底层数据的相关方法封装到了ContextImpl
中。(ContextWrapper
中几乎所有的方法实现都是调用ContextImpl
的相应方法来实现的。)
理解了这一层,对理解Context结构有很大帮助。
相关设计模式
装饰者(Decorator)模式 和 代理模式:
装饰者模式关注点在于动态的添加方法;代理模式关注于控制对对象的访问。
代理模式中,我们通常在代理类中使用类的实例;而在装饰者模式中,我们通常会把原始对象当做一个参数传给装饰者的构造器。