• 极速理解设计模式系列:12.责任链模式(Chain of Responsibility Pattern)


    四个角色:传递者接口(Handler)、具体传递者(ConcreteHandler)、客户端(Client) 

            传递者接口(Handler):定义一个处理请求的接口和实现下一个对象

            具体传递者(ConcreteHandler):如果能够处理就处理,否则让上级处理请求

            客户端(Client) :创立责任链,并向链中对象提出请求

     实现思路:传递者接口设置上级然后提供一个处理请求的方法,在具体传递中如果能够处理就处理,否则就让其上级来处理,客户端组织其责任链,并且设置请求。

     类图:

     

    应用场景:OA系统中的请假审批系统,普通开发者想请假,如果请1天及以下的假则只需要开发经理许可,如果1天<请假天数<=5天则需要总监许可,如果5天<请假天数<=10天则需要副总裁批准,如果请假天数>10天则需要总裁许可。

    分析:在客户端设置责任链和请假审批的上级下级,然后每次普通开发者将请假申请提交到开发经理,如果在开发经理许可范围之内,则处理,否则提交给他的上级总监,以此类推处理这个请假请求。

            下面我们在控制台程序去演示一下如何使用Chain of Responsibility Pattern:

            一、 传递者接口(Handler)

        //传递者接口(Handler)
    abstract class Higher
    {
    public string Name { get; set; }
    public Higher higher;
    public void SetHigher(Higher _Higher)
    {
    this.higher = _Higher;
    }
    public Higher(string name)
    {
    Name = name;
    }
    public abstract void ExeApply(Apply apply);
    }

            二、具体传递者(ConcreteHandler)

        //具体传递者(ConcreteHandler)
    class ManagerHigher : Higher
    {
    public ManagerHigher(string name) : base(name) { }
    public override void ExeApply(Apply apply)
    {
    if (apply.ApplyDay <= 1)
    Console.WriteLine(Name + " 批准 " + apply.ApplyName + " 申请了 " + apply.ApplyDay + "天假期");
    else
    higher.ExeApply(apply);
    }
    }

    //具体传递者(ConcreteHandler)
    class DirectorHigher : Higher
    {
    public DirectorHigher(string name) : base(name) { }
    public override void ExeApply(Apply apply)
    {
    if (apply.ApplyDay <= 5)
    Console.WriteLine(Name + " 批准 " + apply.ApplyName + " 申请了 " + apply.ApplyDay + "天假期");
    else
    higher.ExeApply(apply);
    }
    }

    //具体传递者(ConcreteHandler)
    class VPHigher : Higher
    {
    public VPHigher(string name) : base(name) { }
    public override void ExeApply(Apply apply)
    {
    if (apply.ApplyDay <= 10)
    Console.WriteLine(Name + " 批准 " + apply.ApplyName + " 申请了 " + apply.ApplyDay + "天假期");
    else
    higher.ExeApply(apply);
    }
    }

    //具体传递者(ConcreteHandler)
    class CEOHigher : Higher
    {
    public CEOHigher(string name) : base(name) { }
    public override void ExeApply(Apply apply)
    {
    if (apply.ApplyDay>10)
    Console.WriteLine(Name + " 批准 " + apply.ApplyName + " 申请了 " + apply.ApplyDay + "天假期");
    else
    higher.ExeApply(apply);
    }
    }

            三、客户端(Client)

        class Program
    {
    static void Main(string[] args)
    {
    //责任链模式的创建
    Higher managerHigher = new ManagerHigher("张三经理");
    Higher directorHigher = new DirectorHigher("李四总监");
    Higher vpHigher = new VPHigher("王五副总裁");
    Higher ceoHigher = new CEOHigher("林一总裁");
    managerHigher.SetHigher(directorHigher);
    directorHigher.SetHigher(vpHigher);
    vpHigher.SetHigher(ceoHigher);

    //创建申请人
    Apply liuying = new Apply() { ApplyName = "刘颖", ApplyDay = 5 };
    Apply chenming = new Apply() { ApplyName = "陈明", ApplyDay = 1 };
    Apply zengli = new Apply() { ApplyName = "曾利", ApplyDay = 15 };

    //申请人都将申请提交给经理
    managerHigher.ExeApply(liuying);
    managerHigher.ExeApply(chenming);
    managerHigher.ExeApply(zengli);

    Console.ReadLine();
    }
    }

            申请人

        //申请人
    class Apply
    {
    public string ApplyName { get; set; }
    public double ApplyDay { get; set; }
    }

            如需源码请点击 ResponsibilityPattern.rar  下载。

  • 相关阅读:
    《c++primer》笔记 第3章 字符串、向量和数组
    如何下载Jason2测高数据
    《c++primer》笔记 第2章 变量和基本类型
    《c++primer》笔记 第1章 开始
    VMware打开vmx文件无响应
    Qt5.6.0连接SQL Server 2008
    Qt5.6.0(32位)编译SQLServer驱动(ODBC)(vs2013)
    Qt中操作数据库例子-插入数据
    《UNIX网络编程卷1》第一例及问题
    UVa 1225 Digit Counting
  • 原文地址:https://www.cnblogs.com/chengxingliang/p/2199128.html
Copyright © 2020-2023  润新知