Decorator装饰(结构型模式)
动机:
如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀的问题?从而使得任何“功能扩展变化”所导致的影响降为最低?
意图:
动态地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。
出自:《设计模式》GoF
Decorator模式的几个要点:
1、通过采用组合、而继承的手法,Decorator模式实现了在运行时动态地扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。
2、Component类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于Component类应该透明--换言之Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。
3、Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或者多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。
4、Decorator模式并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”--是为“装饰”的含义。
.NET FCL的输入输出类的整体设计就是一个Decorayor模. 先看一下下面的UML图.

下面是程序源码:
ISimpleWriter.cs
如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀的问题?从而使得任何“功能扩展变化”所导致的影响降为最低?
意图:
动态地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。
出自:《设计模式》GoF
Decorator模式的几个要点:
1、通过采用组合、而继承的手法,Decorator模式实现了在运行时动态地扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。
2、Component类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于Component类应该透明--换言之Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。
3、Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或者多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。
4、Decorator模式并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”--是为“装饰”的含义。
.NET FCL的输入输出类的整体设计就是一个Decorayor模. 先看一下下面的UML图.

下面是程序源码:
ISimpleWriter.cs
1
namespace Filters
2
{
3
/// <summary>
4
/// This interface defines the methods that Oozinoz filters must support.
5
/// </summary>
6
public interface ISimpleWriter
7
{
8
void Write(char c);
9
void Write(string s);
10
void WriteLine();
11
void Close();
12
}
13
}
14
OozinozFilter.cs
namespace Filters2
{3
/// <summary>4
/// This interface defines the methods that Oozinoz filters must support.5
/// </summary>6
public interface ISimpleWriter7
{8
void Write(char c);9
void Write(string s);10
void WriteLine();11
void Close();12
}13
}14

1
using System;
2
namespace Filters
3
{
4
5
public abstract class OozinozFilter : ISimpleWriter
6
{
7
protected ISimpleWriter _writer;
8
9
10
public OozinozFilter(ISimpleWriter writer)
11
{
12
_writer = writer;
13
}
14
15
public abstract void Write(char c);
16
17
18
public virtual void Write(string s)
19
{
20
foreach(char c in s.ToCharArray())
21
{
22
Write(c);
23
}
24
}
25
26
public virtual void WriteLine()
27
{
28
_writer.WriteLine();
29
}
30
31
public virtual void Close()
32
{
33
_writer.Close();
34
}
35
}
36
}
37
SimpleStreamWriter.cs
using System;2
namespace Filters3
{4
5
public abstract class OozinozFilter : ISimpleWriter 6
{7
protected ISimpleWriter _writer;8

9
10
public OozinozFilter(ISimpleWriter writer) 11
{12
_writer = writer;13
} 14
15
public abstract void Write(char c);16

17
18
public virtual void Write(string s)19
{20
foreach(char c in s.ToCharArray())21
{22
Write(c);23
}24
}25
26
public virtual void WriteLine()27
{28
_writer.WriteLine();29
}30
31
public virtual void Close()32
{33
_writer.Close();34
}35
}36
}37

1
using System.IO;
2
namespace Filters
3
{
4
5
public class SimpleStreamWriter : StreamWriter, ISimpleWriter
6
{
7
8
public SimpleStreamWriter(Stream s) : base (s)
9
{
10
}
11
12
public SimpleStreamWriter(string path) : base (path)
13
{
14
}
15
}
16
}
17
TitleCaseFilter.cs
using System.IO;2
namespace Filters3
{4
5
public class SimpleStreamWriter : StreamWriter, ISimpleWriter6
{7
8
public SimpleStreamWriter(Stream s) : base (s) 9
{10
}11
12
public SimpleStreamWriter(string path) : base (path)13
{14
}15
}16
}17

1
using System;
2
namespace Filters
3
{
4
5
public class TitleCaseFilter : OozinozFilter
6
{
7
protected bool inWhite = true;
8
9
public TitleCaseFilter(ISimpleWriter writer) : base (writer)
10
{
11
}
12
13
14
public override void Write(char c)
15
{
16
_writer.Write(inWhite
17
? Char.ToUpper(c)
18
: Char.ToLower(c));
19
inWhite = Char.IsWhiteSpace(c) || c == '\"';
20
}
21
22
public override void WriteLine()
23
{
24
base.WriteLine();
25
inWhite = true;
26
}
27
}
28
}
29
WrapFilter.cs
using System;2
namespace Filters3
{4
5
public class TitleCaseFilter : OozinozFilter 6
{7
protected bool inWhite = true;8
9
public TitleCaseFilter(ISimpleWriter writer) : base (writer)10
{11
} 12
13
14
public override void Write(char c) 15
{16
_writer.Write(inWhite17
? Char.ToUpper(c)18
: Char.ToLower(c));19
inWhite = Char.IsWhiteSpace(c) || c == '\"';20
}21
22
public override void WriteLine()23
{24
base.WriteLine();25
inWhite = true;26
}27
}28
}29

1
using System;
2
using System.Text;
3
namespace Filters
4
{
5
6
public class WrapFilter : OozinozFilter
7
{
8
protected int _width;
9
protected StringBuilder lineBuf = new StringBuilder();
10
protected StringBuilder wordBuf = new StringBuilder();
11
protected bool _center = false;
12
protected bool _inWhite = false;
13
protected bool _needBlank = false;
14
15
public WrapFilter(ISimpleWriter writer, int width) : base (writer)
16
{
17
this._width = width;
18
}
19
20
public bool Center
21
{
22
get
23
{
24
return _center;
25
}
26
set
27
{
28
_center = value;
29
}
30
}
31
32
public override void Close()
33
{
34
Flush();
35
base.Close();
36
}
37
38
public void Flush()
39
{
40
if (wordBuf.Length > 0)
41
{
42
PostWord();
43
}
44
if (lineBuf.Length > 0)
45
{
46
PostLine();
47
}
48
}
49
50
protected void PostLine()
51
{
52
if (Center)
53
{
54
for (int i = 0; i < (_width - lineBuf.Length) / 2; i++)
55
{
56
_writer.Write(' ');
57
}
58
}
59
_writer.Write(lineBuf.ToString());
60
_writer.WriteLine();
61
}
62
63
protected void PostWord()
64
{
65
if (lineBuf.Length + 1 + wordBuf.Length > _width && (lineBuf.Length > 0))
66
{
67
PostLine();
68
lineBuf = wordBuf;
69
wordBuf = new StringBuilder();
70
}
71
else
72
{
73
if (_needBlank)
74
{
75
lineBuf.Append(" ");
76
}
77
lineBuf.Append(wordBuf);
78
_needBlank = true;
79
wordBuf = new StringBuilder();
80
}
81
}
82
83
public override void Write(char c)
84
{
85
if (Char.IsWhiteSpace(c))
86
{
87
if (!_inWhite)
88
{
89
PostWord();
90
}
91
_inWhite = true;
92
}
93
else
94
{
95
wordBuf.Append(c);
96
_inWhite = false;
97
}
98
}
99
}
100
}
101
using System;2
using System.Text;3
namespace Filters4
{5
6
public class WrapFilter : OozinozFilter 7
{8
protected int _width;9
protected StringBuilder lineBuf = new StringBuilder();10
protected StringBuilder wordBuf = new StringBuilder();11
protected bool _center = false;12
protected bool _inWhite = false;13
protected bool _needBlank = false;14
15
public WrapFilter(ISimpleWriter writer, int width) : base (writer)16
{17
this._width = width;18
}19
20
public bool Center21
{22
get 23
{24
return _center;25
}26
set27
{28
_center = value;29
}30
}31
32
public override void Close() 33
{34
Flush();35
base.Close();36
}37
38
public void Flush()39
{40
if (wordBuf.Length > 0)41
{42
PostWord();43
}44
if (lineBuf.Length > 0)45
{46
PostLine();47
}48
}49
50
protected void PostLine() 51
{52
if (Center)53
{54
for (int i = 0; i < (_width - lineBuf.Length) / 2; i++)55
{56
_writer.Write(' ');57
}58
}59
_writer.Write(lineBuf.ToString());60
_writer.WriteLine();61
}62
63
protected void PostWord() 64
{65
if (lineBuf.Length + 1 + wordBuf.Length > _width && (lineBuf.Length > 0))66
{67
PostLine();68
lineBuf = wordBuf;69
wordBuf = new StringBuilder();70
}71
else72
{73
if (_needBlank)74
{75
lineBuf.Append(" ");76
}77
lineBuf.Append(wordBuf);78
_needBlank = true;79
wordBuf = new StringBuilder();80
}81
}82
83
public override void Write(char c) 84
{85
if (Char.IsWhiteSpace(c))86
{87
if (!_inWhite)88
{89
PostWord();90
}91
_inWhite = true;92
}93
else94
{95
wordBuf.Append(c);96
_inWhite = false;97
}98
}99
}100
}101



浙公网安备 33010602011771号