首页 > 其他分享 >责任链

责任链

时间:2022-11-14 21:44:07浏览次数:33  
标签:CalChainBase Invoke 责任 ChainBase context public CalContext

责任链模式如同aspnetcore中的管道机制,贯穿真个框架的开始和结束。很经典的有请假,写个假条找组长,主管 ,经理,boss等一层一层的去批复,当然每个领导批假的天数是具体明确的,要不然就没法传递下去,这里有两个字很关键,就是“传递”。

下面通过一个简单的计算器的例子具体说明。

 public class CalContext
    {
        public decimal[] Args { get; set; }
        public Operator calOperator { get; set; }
        public decimal Result { get; set; }
    }
    public enum Operator
    {
        Add,
        Sub,
        Mul,
        Div
    }

责任链的上下文文本很重要,跟aspnetcore里面的httpcontext一样,起到传递数据承载作用。

  public abstract class CalChainBase
    {
        private CalChainBase _chainBase; //可以通过可空构造函数,效果一样

        public CalChainBase ChainBase { get => _chainBase; set => _chainBase = value; }

        public abstract CalContext Invoke(CalContext context);
    }

上面的代码就是整个链子的传递核心所在,依然是抽象功不可没,CalChainBase看起来就是一个对象,但是它确实一类的抽象,正因为这样所以我们可以通过相同的特征对象来不断的替换它,每次替换都可以完成自己的invoke任务,而这个上下文文本CalContext就是整个数据传输的载体。

   public class AddChain : CalChainBase
    {
        public override CalContext Invoke(CalContext context)
        {
            if (context.calOperator.Equals(Operator.Add))
            {
                context.Result = context.Args.Aggregate((x, y) => (x + y));
                return context;
            }

            if (ChainBase == null)
                throw new ArgumentNullException(nameof(AddChain));
            return ChainBase.Invoke(context);
        }
    }
    public class SubChain : CalChainBase
    {
        public override CalContext Invoke(CalContext context)
        {
            if (context.calOperator.Equals(Operator.Sub))
            {
                context.Result = context.Args.Aggregate((x, y) => (x - y));
                return context;
            }

            if (ChainBase == null)
                throw new ArgumentNullException(nameof(SubChain));
            return ChainBase.Invoke(context);
        }
    }
    public class MulChain : CalChainBase
    {
        public override CalContext Invoke(CalContext context)
        {
            if (context.calOperator.Equals(Operator.Mul))
            {
                context.Result = context.Args.Aggregate((x, y) => (x * y));
                return context;
            }

            if (ChainBase == null)
                throw new ArgumentNullException(nameof(MulChain));
            return ChainBase.Invoke(context);
        }
    }
    public class DivChain : CalChainBase
    {
        public override CalContext Invoke(CalContext context)
        {
            if (context.calOperator.Equals(Operator.Div))
            {
                context.Result = context.Args.Aggregate((x, y) => (x / y));
                return context;
            }

            if (ChainBase == null)
                throw new ArgumentNullException(nameof(DivChain));
            return ChainBase.Invoke(context);
        }
    }

上面的实现顺理成章,通过枚举判断具体的实例,面向对象理解好实例(对象)和类之间的关系尤其重要。这个判断就是把本分之内的事情给做了,如果不归我的话那就往下传递。这里可以给一个终结点输出点东西,提示一下context执行完没有被实际处理,这里我省略。

internal class Program
    {
        static void Main(string[] args)
        {
            CalContext context = new CalContext() { Args = new decimal[] { 1, 2, 3, 4, 5 }, calOperator = Operator.Add };
            CalChainBase start = new AddChain();
            CalChainBase sub = new SubChain();
            CalChainBase mul = new MulChain();
            CalChainBase div = new DivChain();
            start.ChainBase = sub;
            sub.ChainBase = mul;
            mul.ChainBase = div;

            start.Invoke(context);
            Console.WriteLine($"+ result= {context.Result}");

            context.calOperator = Operator.Sub;
            start.Invoke(context);
            Console.WriteLine($"- result= {context.Result}");

            context.calOperator = Operator.Mul;
            start.Invoke(context);
            Console.WriteLine($"* result= {context.Result}");

            context.calOperator = Operator.Div;
            start.Invoke(context);
            Console.WriteLine($"/ result= {context.Result}");

            context.Args = new decimal[] { 100, 200 };
            start.Invoke(context);
            Console.WriteLine($"/ result= {context.Result}");
        }
    }

 

上面的客户端实现就顺理成章了,可以在包装一下,这里省略。

总结,责任链也是处理对象与对象之间的关系,只不过它巧妙地把归于抽象类或者接口的一组实现抽象出来CalChainBase这样的模板。

标签:CalChainBase,Invoke,责任,ChainBase,context,public,CalContext
From: https://www.cnblogs.com/morec/p/16890533.html

相关文章

  • 设计模式学习(十六):责任链模式
    设计模式学习(十六):责任链模式作者:Grey原文地址:博客园:设计模式学习(十六):责任链模式CSDN:设计模式学习(十六):责任链模式责任链模式责任链模式是一种行为型模式。举例说明:有......
  • 设计模式---责任链模式
    简述将各个功能拆分后分别封装(各功能解耦),需要时可自由组合(包括执行顺序)话不多说,看个优化案例吧。优化案例最初版以下是模拟客户端想服务端发送请求的业务流程。......
  • JAVA 责任链设计模式
    这次介绍责任链模式,采用最普遍的请假例子来编码实现。先给列出个模拟的需求,一个人请假,调用一个接口,传入的参数是他请假的天数。然后,请假的天数---->如果小于2天,由直属领导......
  • 山西省忻州市代县宏威水泥有限责任公司 能耗监测系统的设计与应用
    陈盼(安科瑞电气股份有限公司,上海市)摘要:2008年01月03日,北京市建委和市发改委公布了北京实施能源审计的部分北京市国家机关办公建筑和大型公共建筑平均电耗、水耗。2011年江......
  • 最高法-承包人放弃费用索赔要求不能解释为放弃对违约责任的追究
    (2020)最高法民终941号  湖南建工集团有限公司、贵州高速公路集团有限公司建设工程施工合同纠纷二审民事裁定书关键词:索赔时限 建设工程 违约责任 放弃本院认为:......
  • 最高法-当同一件事件同时符合违约责任和索赔责任约定时,守约方可选择择一主张
    (2019)最高法民终491号  湖南省第四工程有限公司、洪洞县交通运输局建设工程施工合同纠纷二审民事判决书关键词:索赔程序 违约责任 建设工程上诉人主张:(二)一审判决判......
  • 设计模式:责任链模式的应用场景及源码应用
    一、概述责任链模式(ChainofResponsibilityPattern)是将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自动维护一个下一节点对象。当一个请求从链式的首......
  • 行为型模式-责任链模式
    概述在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每......
  • 聊一聊责任链模式
    将一堆“事情”串联在一起,有序执行,就叫责任链一、概述责任链模式(ChainofResponsibilityPattern)是将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自......
  • 聊一聊责任链模式
    将一堆“事情”串联在一起,有序执行,就叫责任链一、概述责任链模式(ChainofResponsibilityPattern)是将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自......