用委托来实现简单的可扩展结构

 一说到可扩展结构,大家立即想到插件,想到严谨的结构设计,复杂的程序,众多的接口。确实,很多大型复杂的程序都实现了可扩展结构,这是为了方便用户自己扩展这些程序。但一般的这种结构比较复杂,实现起来比较麻烦。以下是实现一个简单的可扩展结构的例子。
/// <summary>
/// 动作基础类
/// </summary>
public abstract class ActionBase
{
    
/// <summary>
    
/// 动作名称
    
/// </summary>
    public abstract string Name{ get;}
    
/// <summary>
    
/// 执行动作
    
/// </summary>
    public abstract void Execute();
}
/// <summary>
/// 动作集合
/// </summary>
public class ActionList : System.Collections.CollectionBase
{
    
/// <summary>
    
/// 注册动作
    
/// </summary>
    
/// <param name="a"></param>
    public void Registe( ActionBase a )
    {
        
this.InnerList.Add( a );
    }
    
/// <summary>
    
/// 获得指定名称的动作
    
/// </summary>
    public ActionBase thisstring name ]
    {
        
get
        {
            
foreach( ActionBase a in this.InnerList )
            {
                
if( a.Name == name )
                    
return a ;
            }
            
return null;
        }
    }
    
/// <summary>
    
/// 指定指定名称的动作
    
/// </summary>
    
/// <param name="name">动作名称</param>
    public void Execute( string name )
    {
        ActionBase a 
= this[ name ];
        
if( a != null )
            a.Execute();
    }
}
//public class ActionList : System.Collections.CollectionBase

internal class MyAction1 : ActionBase
{
    
public override string Name
    {
        
getreturn "action1";}
    }
    
public override void Execute()
    {
        System.Console.WriteLine( 
"Action1 execute");
    }
}
internal class MyAction2 : ActionBase
{
    
public override string Name
    {
        
getreturn "action2";}
    }
    
public override void Execute()
    {
        System.Console.WriteLine( 
"Action2 execute");
    }
}

public class StartApplication
{
    
public static void Main()
    {
        ActionList list 
= new ActionList();
        list.Registe( 
new MyAction1());
        list.Registe( 
new MyAction2());

        list.Execute(
"action1");
    }
}
//public class StartApplication

从上面的例子可以看出,实现一个可扩展结构需要很多类来支持。在很多情况下,我们只是需要简单的可扩展结构,而这种实现方式也太复杂臃肿了。

有时可以使用反射来实现简单的可扩展结构,例如微软.NET框架下的System.Xml.Xsl.XslTransform内部就使用了反射来实现对XSLT函数的扩展。但反射可能存在安全和性能问题,而且存在不方便调试的情况。

在此我提出使用委托来实现简单的可扩展结构。委托性能比反射好,安全而且便于调试。其例子为

 

/// <summary>
/// 定义委托类型
/// </summary>
public delegate void ActionMethodDelegate();

/// <summary>
/// 动作集合
/// </summary>
public class ActionList2 
{
    
private System.Collections.Hashtable myTable = new System.Collections.Hashtable();
    
/// <summary>
    
/// 注册动作
    
/// </summary>
    
/// <param name="name">动作名称</param>
    
/// <param name="targe">方法</param>
    public void Registe( string name , ActionMethodDelegate targe )
    {
        myTable[ name ] 
= targe ;
    }
    
/// <summary>
    
/// 执行指定名称的动作
    
/// </summary>
    
/// <param name="name">动作名称</param>
    public void Execute( string name )
    {
        ActionMethodDelegate targe 
= myTable[ name ] as ActionMethodDelegate ;
        
if( targe != null )
            targe();
    }
}

public class FunctionClass
{
    
public static void Action1()
    {
        System.Console.WriteLine( 
"Action1 execute");
    }
    
public static void Action2()
    {
        System.Console.WriteLine(
"Action2 execute");
    }
}

public class StartApplication2
{
    
public static void Main()
    {
        ActionList2 list 
= new ActionList2();
        list.Registe( 
"action1" , new ActionMethodDelegate( FunctionClass.Action1 ));
        list.Registe( 
"action2" , new ActionMethodDelegate( FunctionClass.Action2 ));

        list.Execute( 
"action2");
    }
}


从上面的例子可以看出,使用委托来实现简单的可扩展结构,代码量和类的数量大大减少,而且扩展起来非常容易,只要实现某个静态函数,然后调用Registe函数注册一下就可以了。

对于有些按照名称调用功能的程序结构,一般的是使用switch-case结构来实现,现在可以考虑使用这种委托的可扩展结构,避免大型的switch-case语句,添加和删除功能比较方便,有利于函数的相互独立,而且便于扩展。

由于委托能接受参数,因此可以使用委托来实现稍微复杂的可扩展结构,但对于比较复杂功能强的可扩展结构,委托可能还不够,还得使用老办法。

XDesigner软件工作室( http://www.xdesigner.cn ) 2006-9-15

posted on 2006-09-15 11:03  袁永福 电子病历,医疗信息化  阅读(1975)  评论(4编辑  收藏  举报

导航