Android常用设计模式-装饰者模式

Android中的装饰者模式

装饰者模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。它比子类的方式更加灵活。隔离了对主类的入侵,易于扩展。

装饰者的定义离不开这四个角色,我们理清楚这个概念就能依葫芦画瓢完成自己的装饰器。

四个角色:

  1. 抽象组件:接口或者抽象类,被装饰的最原始的对象。具体组件与抽象装饰角色的父类。
  2. 具体组件:实现抽象组件的接口或抽象类的具体的对象。
  3. 抽象装饰器:接口或者抽象类,它是抽象组件的子类,同时持有一个被装饰者的引用,用来调用被装饰者的方法,同时可以给被装饰者增加新的职责。
  4. 具体装饰类:抽象装饰角色的具体实现。

如何定义

比如我们使用充电宝为例。

抽象组件

最基本的只能充电。

/**
 * 定义一个充电宝的基本逻辑,充电
 *
 * 这里可以用接口,可以用类,可以用抽象 都是可以的
 * 只是不同的定义方法,可以默认实现一些重写方法,更加方便而已
 */
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

Android常用设计模式-装饰者模式

对 Context 抽象类进行装饰,黄色标记是 Context 抽象类的抽象方法,红色是对 Context 抽象类进行的扩展方法。

比如Service和Activity就会继承具体装饰类 ContextWrapper 从而实现上下文的创建等一些逻辑。

总结

除此之外,在我们应用开发的过程中我们也有很多场景会用到装饰者模式。大家理解之后可以很好的应用。

使用的场景:

  • 需要扩展一个类的功能,或给一个类添加附加职责。
  • 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
  • 无法或不方便使用继承的时候。

优缺点:

  • 优点 扩展对象功能,灵活性高。
  • 缺点 增加复杂性

此篇只是展示装饰者模式的概念与基本使用,后期会单独出一些实战的文章。