0%

设计模式之装饰者模式

定义:动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。

装饰模式和代理模式有点类似,有时甚至容易混淆,倒不是说会把代理当成装饰,而常常会将装饰看作代理。装饰模式是以客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,给爱用继承的人一个全新的设计眼界; 而代理模式则是给一个对象提供一个代理对象,并由代理对象来控制对原有对象的引用。

装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,但不对对象本身的功能进行增强。

装饰者模式类图

装饰者和被装饰者必须是一样的类型,也就是有共同的超类,这是相当关键的地方。在这里,利用继承达到“类型匹配”,而不是利用继承获得“行为”。行为来自装饰者和基础组件,或与其他装饰者之间的组合关系。

1. Java中的装饰者:Java I/O

真实世界的装饰者:Java I/O

装饰java.io类

Java I/O也引出装饰者模式的一个“缺点”:利用装饰者模式,常常造成设计中有大量的小类,数量实在太多了,可能会造成使用此API程序员的困扰。

2. Android中的装饰者:Context

Android中Context类图

从图中我们可以看出,ContextImpl和ContextWrapper继承自Context,ContextWrapper内部包含有Context类型的mBase对象,mBase具体指向的是ContextImpl。ContextImpl提供了很多功能,但是外界需要使用并拓展ContextImpl的功能,因此设计上使用了装饰模式,ContextWrapper是装饰类,它对ContextImpl进行包装,ContextWrapper主要是起了方法传递作用,ContextWrapper中几乎所有的方法实现都是调用ContextImpl的相应方法来实现的。

ContextThemeWrapper、Service和Application都继承自ContextWrapper,这样他们都可以通过mBase来使用Context的方法,同时它们也是装饰类,在ContextWrapper的基础上又添加了不同的功能。

ContextThemeWrapper中包含和主题相关的方法(比如: getTheme方法),因此,需要主题的Activity继承ContextThemeWrapper,而不需要主题的Service则继承ContextWrapper。