Android常用设计模式-装饰者模式
Android中的装饰者模式
装饰者模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。它比子类的方式更加灵活。隔离了对主类的入侵,易于扩展。
装饰者的定义离不开这四个角色,我们理清楚这个概念就能依葫芦画瓢完成自己的装饰器。
四个角色:
- 抽象组件:接口或者抽象类,被装饰的最原始的对象。具体组件与抽象装饰角色的父类。
- 具体组件:实现抽象组件的接口或抽象类的具体的对象。
- 抽象装饰器:接口或者抽象类,它是抽象组件的子类,同时持有一个被装饰者的引用,用来调用被装饰者的方法,同时可以给被装饰者增加新的职责。
- 具体装饰类:抽象装饰角色的具体实现。
如何定义
比如我们使用充电宝为例。
抽象组件
最基本的只能充电。
/**
* 定义一个充电宝的基本逻辑,充电
*
* 这里可以用接口,可以用类,可以用抽象 都是可以的
* 只是不同的定义方法,可以默认实现一些重写方法,更加方便而已
*/
abstract class PortableBattery {
abstract fun charge()
}
具体组件
实现上述抽象组件的具体类,比如我们定义一个小米充电宝。
/**
* 小米充电宝,默认的实现就是可以充电的
*/
class MiProtableBattery : PortableBattery() {
override fun charge() {
YYLogUtils.w("使用小米充电宝充电")
}
}
抽象装饰器
修改或扩展充电宝的功能。比如我们给充电宝加一个照明功能。
我们把之前的抽象当构造定义在新的抽象装饰器中。我们可以修改之前的实现,也可以添加新的实现:
/**
* 定义一个充电宝的装饰类
*
*/
abstract class PortableBatteryDecorator(private val portableBattery: PortableBattery) : PortableBattery() {
//重写父类的方法,这里可以直接调用父类方法,也可以修改之后自行调用
override fun charge() {
portableBattery.charge()
}
//我们还能通过这样的装饰类扩展他的方法
abstract fun lighting()
}
具体装饰类
我们实现的是装饰类,我们可以自行调用照明,也可以在充电的时候调用照明,一切都很灵活。
/**
* 小米充电宝2,实现的是装饰类
*/
class Mi2ProtableBattery(private val portableBattery: PortableBattery) : PortableBatteryDecorator(portableBattery) {
override fun charge() {
super.charge()
//我们就能让充电宝2 一边充电一边照明
lighting()
}
override fun lighting() {
YYLogUtils.w("充电的时候打开照明灯")
}
}
使用
fun decoratorTest() {
val mMiProtableBattery = MiProtableBattery()
// mMiProtableBattery.charge()
val mMi2ProtableBattery = Mi2ProtableBattery(mMiProtableBattery)
mMi2ProtableBattery.charge()
}
我们实现小米充电宝的具体类,然后使用装饰器包裹小米充电宝,那么现在就能使用装饰类的方法,从而实现小米充电宝2的一边充电一边照明的功能实现。
装饰者模式在Android的源码设计中也有提现,比如我们常见的 ContextWrapper
对 Context 抽象类进行装饰,黄色标记是 Context 抽象类的抽象方法,红色是对 Context 抽象类进行的扩展方法。
比如Service和Activity就会继承具体装饰类 ContextWrapper 从而实现上下文的创建等一些逻辑。
总结
除此之外,在我们应用开发的过程中我们也有很多场景会用到装饰者模式。大家理解之后可以很好的应用。
使用的场景:
- 需要扩展一个类的功能,或给一个类添加附加职责。
- 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
- 无法或不方便使用继承的时候。
优缺点:
- 优点 扩展对象功能,灵活性高。
- 缺点 增加复杂性
此篇只是展示装饰者模式的概念与基本使用,后期会单独出一些实战的文章。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站。本站所有源码与软件均为原作者提供,仅供学习和研究使用。如您对本站的相关版权有任何异议,或者认为侵犯了您的合法权益,请及时通知我们处理。