NET框架中的 Decorator 和 Strategy 模式

NET框架中的 Decorator 和 Strategy 模式

        应用场景:net 框架下的TextWriter,HtmlTextWriter,CssTextWriter,IndentedTextWriter 等
        先看一下Decorator 模式结构图:


    NET 下的 Decorator 模式(TextWriter及其派生类):


   
虽然图形有所不同,但大致结构相似。

    这里就大概先分析一下吧。

    TextWriter 作为 一个抽象类定义形式如下:
 
    public abstract class TextWriter : MarshalByRefObject, IDisposable
    {
      .....

      public virtual Write(...);
      .....
      public virtual WriteLine(...);
      .....
    }
   
    里面的Write及WriteLine函数全部是虚方法,因此可以在子类中被重写, 我们一会能看到子类中的这些方法会在调用基类方法之前
进行一些其它的操作:)

    派生类(以HtmlTextWriter 为例)声明如下:

    public class HtmlTextWriter : TextWriter
    {
      .....

      public virtual Write(...);
      .....
      public virtual WriteLine(...);
      .....
    }
 
    这里用其中的Write(bool value)函数说明如下:

    public override void Write(bool value)
    {
     if (this.tabsPending)             --->先进行“添加职责”操作
     {
            this.OutputTabs();            
     }
        this.writer.Write(value);         --->最后调用基类方法
    }

   
    这里就是这种模式所说的"在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。"

    备注:1 .CssTextWriter, SyncTextWriter 类只是将TextWriter作为构造参数传入,未进行"添加职责"的处理,同时
     这两个类的声明如下:
  internal sealed class CssTextWriter : TextWriter
  internal sealed class SyncTextWriter : TextWriter, IDisposable

 
         2. IndentedTextWriter 类与HtmlTextWriter在Write函数中大同小异, 代码如下:
  public override void Write(bool value)
  {
      this.OutputTabs();
      this.writer.Write(value);
  }

         3. StreamWriter,StringWriter 的实现与其它的Writer类有差异,可参考的使用方法如下:
            IndentedTextWriter tw = new IndentedTextWriter(new StreamWriter(_strFileName, false), "");
     ......
     HtmlTextWriter  htw = new IndentedTextWriter(new   StreamWriter(memoryStream,   Encoding.GetEncoding("GB18030")));
            ......
     HtmlTextWriter writer=new HtmlTextWriter(new System.IO.StringWriter());
            ......

     总体上说,Decorator 结构还是很清楚的,也很好理解。这里再把这种模式的意图和适用性拷贝如下,以加深理解:

     意图:  动态地给一个对象添加一些额外的职责。就增加功能来说,比生成子类更为灵活。

     适用性: 1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
      2. 处理那些可以撤消的职责。
      3. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产
  生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于
  生成子类。 


     相关参考: http://topic.csdn.net/t/20040325/09/2883578.html
        http://hi.baidu.com/xiao0856/blog/item/e96479d0855fb18ea0ec9cc5.html
   

 

    
 
      下面,接着再说一下这个架构下的另一个模式 Strategy
 
      还是先看一下Strategy 模式的结构图:


      NET 下的 Strategy 模式(Stream及其派生类):

          

      相信大家已看清楚了,基本上调用的流程如下:
 
      StreamWriter 对象实例--->Write--->Flush(bool flushStream, bool flushEncoder)

      Flush函数的实现如下:

      private void Flush(bool flushStream, bool flushEncoder)
      {
     if (this.stream == null)
     {
         __Error.WriterClosed();
     }

     if (((this.charPos != 0) || flushStream) || flushEncoder)
     {

         if (!this.haveWrittenPreamble)
         {
             this.haveWrittenPreamble = true;
             byte[] preamble = this.encoding.GetPreamble();
             if (preamble.Length > 0)
             {
                 this.stream.Write(preamble, 0, preamble.Length);    //调用指定的STREAM对象的write函数
             }
         }
                int count = this.encoder.GetBytes(this.charBuffer, 0, this.charPos, this.byteBuffer, 0, flushEncoder);
         this.charPos = 0;
         if (count > 0)
         {
             this.stream.Write(this.byteBuffer, 0, count);   //调用指定的STREAM对象的write函数
         }
         if (flushStream)
         {
             this.stream.Flush();
         }
     }
 }

      到这里大家就该明白了吧:)
      调用的方式可以是这样(以FileStream为例):
 FileStream fs = new FileStream(Server.MapPath(".")+"\\test.txt",FileMode.Create,FileAccess.Write);
        StreamWriter sw = new StreamWriter(fs);
        sw.WriteLine("这里是内容");
        ......
        sw.Close();
        fs.Close();

      这里再把这种模式的意图和适用性拷贝如下,以加深理解:
      意图:    定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
      适用性:  1. 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
        2. 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时[ H O 8 7 ] ,可以使用策略模式。
        3. 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
        4. 一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的S t r a t e g y 类中以代替这些条件语句。 

 

        推广:其实将上面的类图中的StreamWriter 换成 StreamReader, 也是这个模式,只不过这两个类在.net 共存而已。


        这里把这两个模式一起抬出来只是因为在分析类似Writer,Reader类时同时发现的,为了体现整个性才一起搬出来:)

        因为这篇文章的内容只是学习.net框架时的“副产品”,因此里面的内容可读性不强,同时肯定会有偏颇之
处。如果大家有不同意见,希望回复本人,以纠正本人的误解,希望不要误导大家:)
 
  

 

 

posted @ 2007-07-31 17:43  代震军  阅读(2449)  评论(5编辑  收藏  举报