必知必会的设计模式1

装饰模式(Decorator Pattern)

属结构型设计模式,也称包装模式,「动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更为灵活」

怎么理解呢?装饰模式的关键角色有两个,一是功能对象,一是装饰类。动态是指可以在不改变逻辑功能源码基础上,仅对装饰类进行调整来满足需求。灵活是指对一个功能对象进行扩展时,可以避免使用继承的方式,这样即减小了影响范围,又很容易的增加功能。

装饰模式.jpg

优缺点

  • 装饰类与被装饰类互相解耦。

  • 是继承关系的一种替代。

  • 动态,灵活是最大的优点。

  • 缺点是切记不要多层装饰。

适用场景

  • 需要扩展某个类的功能

  • 需要动态调整一个对象的功能(增加或移除)

其实说白了,还是基于开始的那段话,在实际项目中,要能预见未来需求或者能对当前需求进行内容再扩展,如果有上述场景的倾向,那我觉得就可以用。就装饰模式的实现上来说,所需要的类以及关系层级并不复杂,即使用的不合适,也只是代码上稍微冗余了些,副作用应该可以忽略的。

在 Android 中的使用

Activity,Service,Application 都作为 Context 场景存在,想象一下,如果他们的实现采用继承的方式,那么一些公共的功能可以在 Context 中定义,特殊的功能需要各自实现。如果各自的功能需要用到同样的资源,那么各自都要持有,导致各自的实现出现冗余,类也随之庞大起来。并且后期如果功能改动调整,就会出现上面说的不够灵活。如果用子类实现的话,就会存在类膨胀的问题。

当然上面这个只是我假想的情况,至于为什么 Context 相关的类采用装饰模式,我也不知道,说不定装饰模式也不一定是最优解。但既然实际情况是这样,那就简单对照着理解理解。

如果对 Context 的实现不太了解,可以先看看这篇 关于 Android Context 知道这些就可以了 有个大概了解。

Context 即是装饰模式中的核心抽象类,它定义了一些功能,ContextImpl 继承自 Context,是 Context 的功能实现类。装饰类是 ContextWrapper 也继承自 Context,其内部持有一个 Context 对象引用。与标准装饰模式不同的是,ContextWrapper 不是抽象类,它也提供了一些自己的方法,而不仅仅重写 Context 的方法。最后 Activity, Service,Application 都继承自 ContextWrapper,定义和实现各自的功能。在创建他们的时候会同时创建相对应的 ContextImpl 对象,并赋值给 ContextWrapper(这个 ContextWrapper 对象其实就是 Activity 等具体子类) 内的 Context 类型对象,所以像平常调用的 startActivity, bindService 等方法最终都是通过 ContextImpl 对象来完成的。

参考内容

「设计模式之禅(第 2 版)」
「Android 源码设计模式解析与实战」

你可能感兴趣的:(必知必会的设计模式1)