• 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


  • 相关阅读:
    类和迭代器
    使用委托调用函数
    自定义类和集合
    带函数的参数返回函数的最大值
    使用程序调试输出窗口
    自定义类
    类和结构
    全局参数
    带参数的函数返回数组之和
    IS运算符
  • 原文地址:https://www.cnblogs.com/walker/p/480241.html
Copyright © 2020-2023  润新知