索引

别名

  • 包装器(Wrapper)

意图

动态地给一个对象添加一些额外的职责。

就增加功能来说,Decorator 模式相比生成子类更为灵活。

Attach additional responsibilities to an object dynamically.

Decorators provide a flexible alternative to subclassing for extending functionality.

结构

参与者

Component

  • 定义一个对象接口,可以给这些对象动态地添加职责。

ConcreteComponent

  • 定义一个对象,可以给这个对象添加一些职责。

Decorator

  • 维持一个指向 Component 对象的指针,并定义一个与 Component 接口一致的接口。

ConcreteDecorator

  • 向组件添加职责。

适用性

在以下情况下可以使用 Decorator 模式:

  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤销的职责。
  • 当不能采用生成子类的方法进行扩充时。

缺点

  • Decorator 是一个透明的包装,其与 Component 还是有些差别的。
  • 采用 Decorator 模式进行系统设计往往会产生许多看上去类似的小对象。导致很难学习系统,排错也很困难。

效果

  • 比静态继承更灵活。
  • 避免在层次结构高层的类有太多的特征。

相关模式

  • Decorator 模式不同于 Adapter 模式,因为 Decorator 仅改变对象的职责而不改变它的接口,而 Adapter 将给对象一个全新的接口。
  • 可以将 Decorator 视为一个退化的、仅有一个组件的 Composite。然而,Decorator 仅给对象添加额外的职责,它的目的不在于对象聚集。
  • 用一个 Decorator 可以改变对象的外表,而 Strategy 模式使得你可以改变对象的内核。这是改变对象的两种途径。
  • 当 Component 类原本就很庞大时,使用 Decorator 模式的代价太高,Strategy 模式相对更好一些。

实现

实现方式(一):Decorator 对象的接口必须与它所装饰的 Component 的接口保持一致。

所有的 ConcreteDecorator 类必须有一个公共的父类。

使用 Decorator 模式仅从外部改变组件,因此组件无需对它的装饰有任何了解,也就是说,这些装饰对该组件是透明的。

 namespace DecoratorPattern.Implementation1
{
public abstract class Component
{
public abstract void Operation();
} public class ConcreteComponent : Component
{
public override void Operation()
{
// do something
}
} public abstract class Decorator : Component
{
private Component _component; public Decorator(Component component)
{
_component = component;
} public override void Operation()
{
_component.Operation();
}
} public class ConcreteDecorator : Decorator
{
public ConcreteDecorator(Component component)
: base(component)
{
} public override void Operation()
{
base.Operation();
AddedBehavior();
} private void AddedBehavior()
{
// do some other things
}
} public class Client
{
public void TestCase1()
{
Component component1 = new ConcreteComponent();
Component component2 = new ConcreteDecorator(component1); component2.Operation();
}
}
}

实现方式(二):省略抽象的 Decorator 类。

当仅需要添加一个职责是,没有必要定义抽象的 Decorator 类。

这时可以把 Decorator 向 Component 转发请求的职责合并到 ConcreteDecorator 中。

 namespace DecoratorPattern.Implementation2
{
public abstract class Component
{
public abstract void Operation();
} public class ConcreteComponent : Component
{
public override void Operation()
{
// do something
}
} public class ConcreteDecorator : Component
{
private Component _component; public ConcreteDecorator(Component component)
{
_component = component;
} public override void Operation()
{
_component.Operation();
AddedBehavior();
} private void AddedBehavior()
{
// do some other things
}
} public class Client
{
public void TestCase1()
{
Component component1 = new ConcreteComponent();
Component component2 = new ConcreteDecorator(component1); component2.Operation();
}
}
}

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

设计模式之美:Decorator(装饰)的更多相关文章

  1. 设计模式(八)装饰器模式Decorator(结构型)

    设计模式(八)装饰器模式Decorator(结构型) 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法 ...

  2. ④ 设计模式的艺术-10.装饰(Decorator)模式

    职责 装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 装饰模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对 ...

  3. 设计模式(三)装饰者模式Decorator

    装饰者模式针对的问题是:对一个结构已经确定的类,在不改变该类的结构的情况下,动态增加一些功能. 一般来说,都是对一些已经写好的架构增加自己的功能,或者应对多种情况,增加功能. 我们还是来玩一句红警,首 ...

  4. 设计模式之美:Role Object(角色对象)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Role Object 的示例实现. 意图 通过明确地附加角色对象到目标对象中,以使对象可以适配不同的客户需求.每个角色对象都代 ...

  5. 设计模式之美:Structural Patterns(结构型模式)

    结构型模式涉及到如何组合类和对象以获得更大的结构. 结构型类模式采用继承机制来组合接口实现. 结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法. 因为 ...

  6. 设计模式之美:Extension Object(扩展对象)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):使用示例结构实现 Extension Object. 实现方式(二):使用泛型实现 IExtensibleObject<T ...

  7. 设计模式之美:Proxy(代理)

    索引 别名 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):使用相同 Subject 接口实现 Proxy. 别名 Surrogate 意图 为其他对象提供一种代理以控制对这个对象的 ...

  8. 设计模式之美:Composite(组合)

    索引 意图 结构 参与者 适用性 缺点 效果 相关模式 实现 实现方式(一):在 Component 中定义公共接口以保持透明性但损失安全性. 意图 将对象组合成树形结构以表示 “部分-整体” 的层次 ...

  9. 设计模式之美:Adapter(适配器)

    索引 别名 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):简单直接的对象适配器. 实现方式(二):实现双向类适配器. 别名 包装器(Wrapper) 意图 将一个类的接口转换成客户 ...

随机推荐

  1. C++STL算法速查

      非变易算法 /* 第21章 非变易算法 Non-modifying sequence operations 21.0 advance, distance 为了了解模板,先了解一下这两个迭代器操作函 ...

  2. 一个用php实现的获取URL信息的类

    获取URL信息的类 使用这个类,你能获得URL的如下信息: - Host  - Path  - Statuscode (eg. 404,200, ...)  - HTTP Version  - Ser ...

  3. Docker上运行dotnet core

    下载microsoft/dotnet镜像 运行命令: docker pull microsoft/dotnet 如果没有使用阿里镜像加速的,参照这篇先配置好再跑上面命令: http://www.cnb ...

  4. jquery.fileupload插件的简易使用日志

    来源:http://yixiandave.iteye.com/blog/1897330 本文内容主要包含fileupload插件传递参数和取回服务器返回数据的方法 jquery.fileupload官 ...

  5. grep 和 wc命令 --- !管道命令!

    Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expr ession Print,表示全局正则表 ...

  6. Filter过滤器简单应用( 接口访问控制 )

    一.描述 在提供安卓.IOS客户端接口时,可以在登陆接口分配Session给客户端,用于判断其他接口是否是合法访问,以避免将所有的接口都暴露在web中可以由路径直接访问.但是最近的一个项目中的移动接口 ...

  7. 比较两个Long对象值

    比较两个Long对象的值是否相等,不可以使用双等号进行比较,(long int Integer可以用双等号进行比较)可以采用如下方式: 1.使用equals方法进行比较 Long a=new Long ...

  8. C#完美实现斐波那契数列

    /// <summary>         /// Use recursive method to implement Fibonacci         /// </summary ...

  9. 【Java学习笔记】泛型

    泛型: jdk1.5出现的安全机制 好处: 1.将运行时期的问题ClassCastException转到了编译时期. 2.避免了强制转换的麻烦. <>: 什么时候用? 当操作的引用数据类型 ...

  10. LeetCode OJ-- Scramble String ***@

    https://oj.leetcode.com/problems/scramble-string/ 一个字符串的混排变换,简直太妙了,好题 class Solution { public: bool ...