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
 1namespace 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
 1using System;
 2namespace 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
 1using System.IO;
 2namespace 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
 1using System;
 2namespace 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
  1using System;
  2using System.Text;
  3namespace 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


原文地址:https://www.cnblogs.com/walker/p/480241.html