在 面向对象 设计和开发过程, 可能会经常遇到以下的情况: 我们需要为一个已经定义好的类添加新的职责(操作), 通常的情况我们会给定义一个新类继承自定义好的类,这样会带来一个问题( 将在本模式的讨论中给出)。通过继承的方式解决这样的情况还带来了系统的复杂性,因为继承的深度会变得很深。
而Decorator 提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合。有关这些内容在讨论中进一步阐述。
别名
包装器(Wrapper)
意图
动态地给一个对象添加一些额外的职责。
就增加功能来说,Decorator 模式相比生成子类更为灵活。
结构
Decorator模式典型的结构图为:

用Decorator给ConcreateComponent对象添加一个新功能,addedbehavior()。
在 结 构 图 中 , ConcreteComponent 和 Decorator 需 要 有 同 样 的 接 口 , 因 此ConcreteComponent 和 Decorator 有着一个共同的父类。这里有人会问,让 Decorator 直接维护一个指向ConcreteComponent 引用(指针) 不就可以达到同样的效果, 答案是肯定并且是否定的。 肯定的是你可以通过这种方式实现, 否定的是你不要用这种方式实现, 因为通过这种方式你就只能为这个特定的ConcreteComponent 提供修饰操作了,当有了一个新的ConcreteComponent 你 又 要 去 新 建 一 个 Decorator 来 实 现 。 但 是 通 过 结 构 图 中 的ConcreteComponent 和 Decorator 有一个公共基类, 就可以利用 OO 中多态的思想来实现只要是Component 型别的对象都可以提供修饰操作的类,这种情况下你就算新建了 100 个Component 型别的类 ConcreteComponent,也都可以由 Decorator 一个类搞定。这也正是Decorator 模式的关键和威力所在了。当然如果你只用给 Component 型别类添加一种修饰, 则 Decorator 这个基类就不是很必要了。
当你向旧的类中添加新代码时,一般是为了添加核心职责或主要行为。而当需要加入的仅仅是一些特定情况下才会执行的特定的功能时(简单点就是不是核心应用的功能),就会增加类的复杂度。装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。
Decorator 模式和 Proxy 模式的相似的地方在于它们都拥有一个指向其他对象的引用 (指针), 即通过组合的方式来为对象提供更多操作 (或者Decorator 模式) 间接性 ( Proxy 模式)。但是他们的区别是,Proxy 模式会提供使用其作为代理的对象一样接口, 使用代理类将其操作都委托给Proxy 直接进行。这里可以简单理解为组合和委托之间的微妙的区别了
网友评论