**修饰模式**，是面向对象程式领域中，一种动态地往一个類別中添加新的行为的设计模式。就功能而言，修饰模式相比生成子類別更为灵活，这样可以给某个对象而不是整个類別添加一些功能。

UML 修饰模式的UML类图

介绍
--

通过使用修饰模式，可以在运行时扩充一个類別的功能。原理是：增加一个修饰类包裹原来的類別，包裹的方式是在修饰类的构造函数中将原来的类以参数的形式传入。装饰类实现新的功能，但是，在不需要用到新功能的地方，它可以直接调用原来的類別中的方法。修饰类必须和原来的類別有相同的接口。

修饰模式是類別继承的另外一种选择。类继承在编译时候增加行为，而装饰模式是在运行时增加行为。

当有几个相互独立的功能需要扩充时，这个区别就变得很重要。在有些面向对象的编程语言中，類別不能在运行时被创建，通常在设计的时候也不能预测到有哪几种功能组合。这就意味著要为每一种组合创建一个新類別。相反，修饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合。一个修饰模式的示例是JAVA里的Java I/O Streams的实现。

动机
--

舉個例子來說，在一個視窗軟體系統中呈現的一個視窗，為了讓視窗中呈現的內容資料能夠捲動，我们希望给它添加水平或垂直滚动条。假设窗口通过"Window"类实例来表示，并且假设它没有添加滚动条功能。我们可以创建一个子类"ScrollingWindow"来提供，或者我们可以创建一个*ScrollingWindowDecorator*来为已存在的*Window*对象添加这个功能。在这点上，只要是解决方案就可以了。
现在我们假设希望选择给我们的窗口添加边框，同样，我们的原始*Window*类不支持。*ScrollingWindow*子类现在会造成一个问题，因为它会有效的创建一种新的窗口。如果我们想要给所有窗口添加边框，我们必须创建*WindowWithBorder*和*ScrollingWindowWithBorder*子类。显然，这个问题由于被添加类而变得更糟了。对于修饰模式，我们简单的创建一个新类*BorderedWindowDecorator*，在运行时，我们能够使用*ScrollingWindowDecorator*或*BorderedWindowDecorator*或两者结合来修饰已存在的窗口。
一个修饰能够被应用的另一个好例子是当有需要根据某套规则或者几个平行的规则集（不同的用户凭据等）限制访问对象的属性或方法时。

一个对象的属性或方法按照某组规则或几个并行规则(不同用户证书等)需要限制访问时，在这种情况下，不是在原始对象中实现访问控制而是在他的使用中不变或不知道任何限制，并且他被包装在一个访问控制修饰对象中，这个对象能够对允许的原始对象的接口子集服务。

应用
--

Java IO 流为典型的装饰模式。

代码示例
----

### Java

这个JAVA示例使用window/scrolling情境。

```
// The Window interface class
public interface Window {
 public void draw(); // Draws the Window
 public String getDescription(); // Returns a description of the Window
}

// implementation of a simple Window without any scrollbars
public class SimpleWindow implements Window {
 public void draw() {
 // Draw window
 }

 public String getDescription() {
 return "simple window";
 }
}

```

以下类包含所有Window类的decorator，以及修饰类本身。

```
// abstract decorator class - note that it implements Window
public abstract class WindowDecorator implements Window {
 protected Window decoratedWindow; // the Window being decorated

 public WindowDecorator (Window decoratedWindow) {
 this.decoratedWindow = decoratedWindow;
 }
 
 @Override
 public void draw() {
 decoratedWindow.draw();
 }

 @Override
 public String getDescription() {
 return decoratedWindow.getDescription();
 }
}

// The first concrete decorator which adds vertical scrollbar functionality
public class VerticalScrollBar extends WindowDecorator {
 public VerticalScrollBar(Window windowToBeDecorated) {
 super(windowToBeDecorated);
 }

 @Override
 public void draw() {
 super.draw();
 drawVerticalScrollBar();
 }

 private void drawVerticalScrollBar() {
 // Draw the vertical scrollbar
 }

 @Override
 public String getDescription() {
 return super.getDescription() + ", including vertical scrollbars";
 }
}

// The second concrete decorator which adds horizontal scrollbar functionality
public class HorizontalScrollBar extends WindowDecorator {
 public HorizontalScrollBar (Window windowToBeDecorated) {
 super(windowToBeDecorated);
 }

 @Override
 public void draw() {
 super.draw();
 drawHorizontalScrollBar();
 }

 private void drawHorizontalScrollBar() {
 // Draw the horizontal scrollbar
 }

 @Override
 public String getDescription() {
 return super.getDescription() + ", including horizontal scrollbars";
 }
}

```

以下是一个测试程序，它创建了一个包含多重装饰的Window实例(如,包含了垂直的和水平的滚动条),然后输出它的描述：

```
public class Main {
 // for print descriptions of the window subclasses
 static void printInfo(Window w) {
 System.out.println("description:"+w.getDescription());
 }
 public static void main(String[] args) {
 // original SimpleWindow
 SimpleWindow sw = new SimpleWindow();
 printInfo(sw);
 // HorizontalScrollBar mixed Window
 HorizontalScrollBar hbw = new HorizontalScrollBar(sw);
 printInfo(hbw);
 // VerticalScrollBar mixed Window
 VerticalScrollBar vbw = new VerticalScrollBar(hbw);
 printInfo(vbw);
 }
}

```

以下是SimpleWindow及添加了组件HorizontalScrollBar和VerticalScrollBar后的Window测试结果：

```
description:simple window
description:simple window, including horizontal scrollbars
description:simple window, including horizontal scrollbars, including vertical scrollbars

```

### C++

C++代码示例:

```
#include <iostream>

using namespace std;

/\* Component (interface) \*/
class Widget {

public: 
 virtual void draw() = 0; 
 virtual ~Widget() {}
}; 

/\* ConcreteComponent \*/
class TextField : public Widget {

private: 
 int width, height;

public:
 TextField( int w, int h ){ 
 width = w;
 height = h; 
 }
 
 void draw() { 
 cout << "TextField: "<< width << ", "<< height << '\n'; 
 }
};

/\* Decorator (interface) \*/ 
class Decorator : public Widget {

private:
 Widget\* wid; // reference to Widget
 
public:
 Decorator( Widget\* w ) { 
 wid = w; 
 }

 void draw() { 
 wid->draw(); 
 }

 ~Decorator() {
 delete wid;
 }
};

/\* ConcreteDecoratorA \*/
class BorderDecorator : public Decorator { 

public:
 BorderDecorator( Widget\* w ) : Decorator( w ) { }
 void draw() {
 Decorator::draw(); 
 cout << "BorderDecorator" << '\n'; 
 } 
};

/\* ConcreteDecoratorB \*/
class ScrollDecorator : public Decorator { 
public:
 ScrollDecorator( Widget\* w ) : Decorator( w ) { }
 void draw() {
 Decorator::draw(); 
 cout << "ScrollDecorator" << '\n';
 } 
};

int main( void ) {
 
 Widget\* aWidget = new BorderDecorator(
 new BorderDecorator(
 new ScrollDecorator(
 new TextField( 80, 24 ))));
 aWidget->draw();
 delete aWidget;
}

```

### C#

C#代码示例:

```
namespace GSL\_Decorator\_pattern
{
 interface IWindowObject
 {
 void Draw(); // draws the object
 string GetDescription(); // returns a description of the object
 }

 class ControlComponent : IWindowObject
 {
 public ControlComponent()
 {
 }

 public void Draw() // draws the object
 {
 Console.WriteLine( "ControlComponent::draw()" ); 
 }

 public string GetDescription() // returns a description of the object
 {
 return "ControlComponent::getDescription()";
 }
 }

 abstract class Decorator : IWindowObject
 {
 protected IWindowObject \_decoratedWindow = null; // the object being decorated

 public Decorator( IWindowObject decoratedWindow)
 {
 \_decoratedWindow = decoratedWindow;
 }

 public virtual void Draw()
 {
 \_decoratedWindow.Draw();
 Console.WriteLine("\tDecorator::draw() ");
 }

 public virtual string GetDescription() // returns a description of the object
 {
 return \_decoratedWindow.GetDescription() + "\n\t" + "Decorator::getDescription() ";
 }
 }

 // the first decorator 
 class DecorationA : Decorator
 {
 public DecorationA(IWindowObject decoratedWindow) : base(decoratedWindow)
 {
 }

 public override void Draw()
 {
 base.Draw();
 DecorationAStuff();
 }

 private void DecorationAStuff()
 {
 Console.WriteLine("\t\tdoing DecorationA things");
 }

 public override string GetDescription()
 {
 return base.GetDescription() + "\n\t\tincluding "+ this.ToString();
 }

 }// end class ConcreteDecoratorA : Decorator

 class DecorationB : Decorator
 {
 public DecorationB(IWindowObject decoratedWindow) : base(decoratedWindow)
 {
 }

 public override void Draw()
 {
 base.Draw();
 DecorationBStuff();
 }

 private void DecorationBStuff()
 {
 Console.WriteLine("\t\tdoing DecorationB things");
 }

 public override string GetDescription()
 {
 return base.GetDescription() + "\n\t\tincluding "+ this.ToString();
 }

 }// end class DecorationB : Decorator

 class DecorationC : Decorator
 {
 public DecorationC(IWindowObject decoratedWindow) : base(decoratedWindow)
 {
 }

 public override void Draw()
 {
 base.Draw();
 DecorationCStuff();
 }

 private void DecorationCStuff()
 {
 Console.WriteLine("\t\tdoing DecorationC things");
 }

 public override string GetDescription()
 {
 return base.GetDescription() + "\n\t\tincluding "+ this.ToString();
 }

 }// end class DecorationC : Decorator

}// end of namespace GSL\_Decorator\_patternpublic class MyClass

// Main
IWindowObject controlComponent = new ControlComponent();
controlComponent = new DecorationA(controlComponent);
controlComponent = new DecorationB(controlComponent);
controlComponent.Draw();

```

### Go

Go代码示例:

```
package main

import "fmt"

// step1: 编写基础功能，刚开始不需要定义接口
type Base struct {
}
func (b \*Base) Call() string {
 return "base is called"
}

// step2: 将上面的方法声明为接口类型，基础功能中的 Call() 调用自动满足下面的接口
type DecoratorI interface {
 Call() string
}

// step3: 编写新增功能，结构中保存接口类型的参数
type Decorator struct {
 derorator DecoratorI
}

func (d \*Decorator) Call() string {
 return "decorator: "+ d.derorator.Call()
}

func main() {
 base := &Base{}
 fmt.Println(base.Call())

 decorator := Decorator{base}
 fmt.Println(decorator.Call())
}

```

参考资料
----

1. ↑  Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides.. 北京: 机械工业出版社. 2000: 115. ISBN 9787111075752 （中文）.  使用`|accessdate=`需要含有`|url=` (帮助)

外部链接
----

* Article "The Decorator Design Pattern" (Java) by Antonio García and Stephen Wong
* Article "Using the Decorator Pattern" (Java) by Budi Kurniawan
* Sample Chapter "C# Design Patterns: The Decorator Pattern" (C#) by James W. Cooper
* A PHP approach[永久] (PHP)
* A Delphi approach (Delphi)
* A JavaScript implementation
* Jt J2EE Pattern Oriented Framework
* Decorator Pattern with Ruby in 8 Lines (Ruby)

  


|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
软件设计模式 |
| --- |
|  |
| 设计模式 | 

|  |  |
| --- | --- |
| 创建型 | 
* 抽象工厂
* 生成器
* 工厂方法
* 惰性初始
* 原型
* 单例

 |
|  |
| 结构型 | 
* 适配器
* 桥接
* Composite（英语：）
* 修饰
* 外观
* 享元
* 代理

 |
|  |
| 行为型 | 
* 责任链
* 命令
* Interpreter（英语：）
* 迭代器
* 中介者
* Memento（英语：）
* 观察者
* Specification（英语：）
* State（英语：）
* 策略
* 模板方法
* 访问者

 |

 |
|  |
| 并行模式 | 
* 主动对象（英语：）
* 阻止（英语：）
* Binding properties（英语：）
* 双重检查锁定模式
* 异步方法调用
* Guarded suspension（英语：）
* Join（英语：）
* 锁
* Messaging（英语：）
* 监视器
* Proactor（英语：）
* 反应器
* 读写锁
* 调度
* 线程池
* 线程局部存储

 |
|  |
| 架构模式 | 
* ADR（英语：）
* Broker（英语：）
* 主從式架構
* CBD
* DAO
* 主动记录
* 数据映射器
* DDD
* Data transfer object（英语：）
* Front controller（英语：）
* Identity map（英语：）
* Interceptor（英语：）
* 控制反转
* MVC
* 微服務
* MVP
* 單體式應用程式
* 多层架构
* Naked objects（英语：）
* P2P
* 发布/订阅
* REST
* SOA
* Specification（英语：）

 |
|  |
| 云分布式 | 
* 断路器
* CQRS（英语：）
* 补偿交易（英语：）
* 索引表
* 领导者选举（英语：）
* MapReduce
* 物化视图（英语：）
* 管道
* 过滤器（英语：）
* 发布/订阅
* 分片（英语：）
* 节流（英语：）

 |
|  |
| 其他模式 | 
* Blackboard（英语：）
* Business delegate（英语：）
* Composite entity（英语：）
* 委托
* 依赖注入
* Intercepting filter（英语：）
* 惰性載入
* Method chaining（英语：）
* 模拟对象
* 空对象
* 对象池
* Servant（英语：）
* Twin（英语：）
* Type tunnel（英语：）

 |
|  |
| 书籍 | 
* 设计模式：可复用面向对象软件的基础
* 代碼大全
* 企业集成模式（英语：）

 |
|  |
| 人物 | 
* 克里斯托佛·亚历山大
* 埃里希·伽瑪
* Ralph Johnson（英语：）
* John Vlissides（英语：）
* 葛來迪·布區
* 肯特·貝克
* 沃德·坎宁安
* 马丁·福勒
* Robert Martin（英语：）
* Jim Coplien（英语：）
* Douglas Schmidt（英语：）
* Linda Rising

 |
|  |
| 社区 | 
* The Hillside Group（英语：）
* The Portland Pattern Repository（英语：）

 |

 |