This page looks best with JavaScript enabled

装饰者模式

 ·  ☕ 2 min read

使用装饰者模式代替单纯的继承,更好的实现功能的扩展

使用场景

装饰模式应该算是对继承的一种补充,如果单纯的依靠继承扩展类的功能,有时会增加很多子类和继承的层级。

类图

@startuml

interface Component{
+ operation()
}

class ConcreteComponent{
+ operation()
}

abstract class Decoration{
 - Component component
}

Component <|.. ConcreteComponent
Component <|.. Decoration

Decoration o-- Component

class ConcreteDecoration extends Decoration {
+ operation()
}

@enduml

@enduml
  • Component 抽象组件,一个接口或抽象类

  • ConcreteComponent 一个具体的组件,实现了 Component 抽象组件

  • Decoration 装饰角色,是一个抽象类,其中必定有一个私有属性引用 Component 对象

  • ConcreteDecoration 一个具体的装饰者

实例

Android SDK 中的 Context

@startuml

abstract class Context

class ContextImpl extends Context

class ContextWrapper extends Context{
+ Context mBase;
}

class ContextThemeWrapper extends ContextWrapper{
}

ContextImpl -o ContextWrapper

class Application extends ContextWrapper

class Service extends ContextWrapper

class Activity extends ContextThemeWrapper

@enduml

在 Android 中,Context 意为上下文,是一个应用的环境信息接口。Android 中 Activity Service Application 都间接的继承自 Context

Context 是一个抽象类,内部定义了很多方法和静态常量,它的实现类是 ContextImpl

ContextImplContextWrapper 继承自 ContextContextWrapper 内部包含 Context 类型的 mBase 对象,mBase 具体指向 ContextImplContextImpl 提供了很多功能,但是外界需要使用并扩展 ContextImpl 的功能,因此设计上使用了装饰模式ContextWrapper 是装饰类,它对 ContextImpl 进行包装,ContextWrapper 主要起了方法传递的作用,ContextWrapper 中几乎所有方法都是通过调用 mBase 对象引用的 ContextImpl 的相应方法。

这里使用装饰模式有以下优点:

  • 使用者能更方便的使用 Context
  • 如果 ContextImpl 发生了改变,ContextWrapper 也不用修改
  • ContextImpl 的实现不会暴露给使用者
  • 通过组合而非继承的方式扩展 ContextImpl 的功能
Support the author with
alipay QR Code
wechat QR Code

Yang
WRITTEN BY
Yang
Developer