导航

模式探索(1):采用委托实现模版方法

Posted on 2005-12-31 00:07  小象  阅读(215)  评论(0)    收藏  举报

      模版方法的关键是在父类中的非抽象方法中调用抽象方法,子类之间的区别仅仅是实现方法的不同。在.NET中,我们可以采用委托方法实现相同的目的,好处就留给各位看官们评论吧。
       我们先来看看一般情况下如何实现模版方法:
 

using System;

namespace Basic
{
    
/// <summary>
    
/// Class1 的摘要说明。
    
/// </summary>

    class Class1
    
{
        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            AbstractClass Worker
=new ConcreteClass1();
            Console.WriteLine (Worker.TemplateMethod ());
            Worker
=new ConcreteClass2 ();
            Console.WriteLine(Worker.TemplateMethod ());
            Console.ReadLine ();
        }

    }

}


using System;

namespace Basic
{
    
/// <summary>
    
/// AbstractClass 的摘要说明。
    
/// </summary>

    public abstract class AbstractClass
    
{
        
public AbstractClass()
        
{
            
//
            
// TODO: 在此处添加构造函数逻辑
            
//
        }


        
public string TemplateMethod()
        
{
            
string s="";
            s
+=Title();
            s
+=Body();
            
return s;
        }

        
public abstract string Title();
        
public abstract string Body();
    }

}


using System;

namespace Basic
{
    
/// <summary>
    
/// ConcreteClass 的摘要说明。
    
/// </summary>

    public class ConcreteClass1:AbstractClass
    
{
        
public ConcreteClass1()
        
{
            
//
            
// TODO: 在此处添加构造函数逻辑
            
//
        }

        
public override string Title()
        
{
        
return "标题1";
        }

        
public override string Body()
        
{
        
return "内容1";
        }

    }

}


using System;

namespace Basic
{
    
/// <summary>
    
/// ConcreteClass 的摘要说明。
    
/// </summary>

    public class ConcreteClass2:AbstractClass
    
{
        
public ConcreteClass2()
        
{
            
//
            
// TODO: 在此处添加构造函数逻辑
            
//
        }

        
public override string Title()
        
{
        
return "标题2";
        }

        
public override string Body()
        
{
        
return "内容2";
        }

    }

}

结果显示:
标题1内容1
标题2内容2

在来看看用.net的委托来如何实现:
using System;

namespace TemplateMethod
{
    
/// <summary>
    
/// TemplateMethod 的摘要说明。
    
/// </summary>

    public class TemplateMethod
    
{
        
public TemplateMethod()
        
{

        }

        
public delegate float Comp(float a,float b);
        
public Comp myComp;
        
public float DoComp(float[] f)
        
{
        
float nf=float.NaN;
            
foreach(float df in f)
            
{
                
if (float.IsNaN(nf))
                
{
                    nf
=df;
                }

                
else
                
{
                nf
=myComp(nf,df);
                }

                
            }
return nf;
        }

    }

}

  在另一个类中定义与委托相同的方法,这个类可以与TemplateMethod无关,只要其中方法的接口与代理相同即可:
using System;

namespace TemplateMethod
{
    
/// <summary>
    
/// DoComp 的摘要说明。
    
/// </summary>

    public class DoComp
    
{
        
public DoComp()
        
{
        }

        
public float c1(float a,float b)
        
{
            
return a+b;
        }

        
public float c2(float a,float b)
        
{
            
return a*b;
        }

    }

}


好处就是使用时可以动态组装(我认为):
using System;

namespace TemplateMethod
{
    
/// <summary>
    
/// Class1 的摘要说明。
    
/// </summary>

    class Class1
    
{
        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            TemplateMethod tm
=new TemplateMethod ();
            
float[] f={1,2,3,4};
            DoComp c
=new DoComp ();
            tm.myComp 
+=new TemplateMethod .Comp (c.c1 );
            System.Console .WriteLine (tm.DoComp (f).ToString ());
            tm.myComp 
-=new TemplateMethod .Comp (c.c1 );
            tm.myComp 
+=new TemplateMethod .Comp (c.c2 );
            System.Console .WriteLine (tm.DoComp (f).ToString ());
            System.Console .ReadLine ();
        }

    }

}

结果显示:
10
24
采用这种方法可以实现模板方法相同的意图,并且更为灵活。在子类中仅实现不同方法的情况下,这种方法是更好的选择。但是如果在方法中涉及到对象的状态,这种方法则不再适用。