• 动态的链式传递执行


    我通常在想到设计模式中的职责链时, 都会想到A保存B的句柄,比如:

    public class A{

         private B _b;

         void Invoke(){ _b.Invoke() ;  }

    public class B{

         private C _c;

         void Invoke(){ _c.Invoke() ;  }

    当出现多个对象需要串联起来执行是,就需要bulid 他们的关系,让前面知道后的,这样就必须有个factory或builder 来做这件是事情,我估计把这汇总方式称为静态链式;

    下面换种方式来看这个这个问题,我也姑且称它为动态链式; 这应该也是Entlib 拦截器的实现和Castle不一样地方(可能,我已经记不住了);

    这么一种方式为: 

    public delegate void InvokeHandler(GetNextInvokeHandler getNext);  
    public delegate InvokeHandler GetNextInvokeHandler();   //获取下一个Handler

    public class DelegateContainer
    {

    public IList<InvokeHandler> _listDelegates;

    public DelegateContainer() { }

    public DelegateContainer(IList<InvokeHandler> list)
    : this()
    {
    _listDelegates = list;
    }

    public void Invoke(InvokeHandler invoke)
    {
    if (_listDelegates.Count == 0)
    {
    //Do mywork

    invoke(null);
    return;
    }
    int index = 0;
    InvokeHandler delg = _listDelegates[index];
    delg(delegate
    {
    if (_listDelegates.Count > ++index)
    {
    return _listDelegates[index];
    }
    return invoke; //Real InvokeHandler;
    });
    }

    }

    测试方法如下 : 

    [TestClass]
    public class TestDelegateContainer
    {
    [TestMethod]
    public void TestInvoke()
    {
    IList<InvokeHandler> handlers = new List<InvokeHandler>();
    handlers.Add(new InvokeHandler(InjectInvoke1));
    handlers.Add(new InvokeHandler(InjectInvoke2));
    handlers.Add(new InvokeHandler(InjectInvoke3));
    DelegateContainer container = new DelegateContainer(handlers);
    container.Invoke(RealInvoke);
    Assert.IsTrue(1 == _resultCount);
    Assert.IsTrue(_executionStack.Contains("Real Execution"));
    }

    private int _resultCount = 0;
    public void RealInvoke(GetNextInvokeHandler getNext)
    {
    //Domywork
    _executionStack += "Real Execution";
    _resultCount++;
    }

    private string _executionStack = string.Empty;
    public void InjectInvoke1(GetNextInvokeHandler getNext)
    {
    _executionStack += "Invoke1 >>";
    InvokeHandler handler = getNext();
    if (handler != null)
    {
    handler.Invoke(getNext); //这里其实是个关键点
    }
    //Domywork
    }
    public void InjectInvoke2(GetNextInvokeHandler getNext)
    {
    _executionStack += "Invoke2 >>";
    InvokeHandler handler = getNext();
    if (handler != null)
    {
    handler.Invoke(getNext);
    }
    //Domywork

    }
    public void InjectInvoke3(GetNextInvokeHandler getNext)
    {
    _executionStack += "Invoke3 >>";
    InvokeHandler handler = getNext();
    if (handler != null)
    {
    handler.Invoke(getNext);
    }
    //Domywork
    }
    }

    输出结果:

    resultCount:1

    executionStack:'Invoke1 >>Invoke2 >>Invoke3 >>Real Execution'

  • 相关阅读:
    IIS 添加二级应用程序
    VS中发布并调试IIS程序
    未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持。如果希望使用通知,请为此数据库启用 Service Broker
    Flash基础开发习惯指要
    2012云计算扫盲
    flash问题集锦(新手必看)
    Flash常用ActionScript控制语句基本用法祥解
    通过offset值的设置使html元素对齐
    不用float也可以让div横向显示
    QQ空间里写的开发心得
  • 原文地址:https://www.cnblogs.com/pojia/p/3478609.html
Copyright © 2020-2023  润新知