专栏首页编码前线设计模式之责任链模式

设计模式之责任链模式

什么是责任链模式?

在现实生活中,有很多请求并不是一个人说了就算的,例如面试时的工资,低于1万的薪水可能技术经理就可以决定了,但是1万~1万5的薪水可能技术经理就没这个权利批准,可能就需要请求技术总监的批准,所以在面试的完后,经常会有面试官说,你这个薪水我这边觉得你这技术可以拿这个薪水的,但是还需要技术总监的批准等的话。

责任链模式:

某个请求需要多个对象进行处理,从而避免请求的发送者和接收之间的耦合关系。将这些对象连成一条链子,并沿着这条链子传递该请求,直到有对象处理它为止。主要涉及两个角色:

抽象处理者角色(Handler):

定义出一个处理请求的接口。这个接口通常由接口或抽象类来实现。

具体处理者角色(ConcreteHandler):

具体处理者接受到请求后,可以选择将该请求处理掉,或者将请求传给下一个处理者。因此,每个具体处理者需要保存下一个处理者的引用,以便把请求传递下去。 设计思路及代码实现

/// <summary>
/// 采购请求
/// </summary>
public class PurchaseRequest
{
    public double Amount { get; set; }

    public string ProductName { get; set; }

    public PurchaseRequest(string productName, double amount)
    {
        this.ProductName = productName;
        this.Amount = amount;
    }
}
/// <summary>
/// 审批人
/// </summary>
public abstract class Approver
{
    public Approver NextApprover { get; set; }

    public string Name { get; set; }

    public abstract void ProcessRequest(PurchaseRequest request);

    public Approver(string name)
    {
        Name = name;
    }
}
/// <summary>
/// 小头头
/// </summary>
public class Manager : Approver
{
    public Manager(string name)
        : base(name)
    {
    }

    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 10000)
        {
            Console.WriteLine("{0}-{1} approved the request of purshing {2}", this.GetType().Name, Name, request.ProductName);
        }
        else if (NextApprover != null)
        {
            NextApprover.ProcessRequest(request);
        }
    }
}
/// <summary>
/// 副总经理
/// </summary>
public class VicePresident : Approver
{
    public VicePresident(string name)
        : base(name)
    {
    }

    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 50000)
        {
            Console.WriteLine("{0}-{1} approved the request of purshing {2}", this.GetType().Name, Name, request.ProductName);
        }
        else if (NextApprover != null)
        {
            NextApprover.ProcessRequest(request);
        }
    }
}
/// <summary>
/// 总经理
/// </summary>
public class President : Approver
{
    public President(string name)
        : base(name)
    {
    }

    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 100000)
        {
            Console.WriteLine("{0}-{1} approved the request of purshing {2}", this.GetType().Name, Name, request.ProductName);
        }
        else if (NextApprover != null)
        {
            NextApprover.ProcessRequest(request);
        }
    }
}

责任链模式的优缺点

优点:

降低了请求的发送者和接收者之间的耦合。 把多个条件判定分散到各个处理类中,使得代码更加清晰,责任更加明确。

缺点:

在找到正确的处理对象之前,所有的条件判定都要执行一遍,当责任链过长时,可能会引起性能的问题 可能导致某个请求不被处理。 责任链模式的适用场景

在以下场景中可以考虑使用责任链模式:

一个系统的审批需要多个对象才能完成处理的情况下,例如请假系统等。 代码中存在多个if-else语句的情况下,此时可以考虑使用责任链模式来对代码进行重构。

本文分享自微信公众号 - 编码前线(gh_acef1225aadd)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-11-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 建造者模式(Builder Pattern)

    用户只需要给出指定复杂对象的类型和内容; 建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)

    用户1205080
  • Java原生序列化和Kryo序列化性能比较

    最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括:

    用户1205080
  • Android热修复原理解析

    通过上面几个类的关系,和类的查找过程,我们可以发现最终是通过遍历 DexPathList的 dexElements数组进行类的查找加载,当找到类就返回;

    用户1205080
  • 设计模式成长记(一) 抽象工厂模式(Abstract Factory)

    目录 定义 UML类图 参与者 编写代码 特点 定义 提供一个创建一系列相关或相互依赖的对象的接口,而无需指定具体的类。 使用频率: ? UML类图 ? 参...

    刘皓
  • C++虚基类

    如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。C++提供虚基类的方法,使得在继承...

    卡尔曼和玻尔兹曼谁曼
  • [译]ASP.NET Core中使用MediatR实现命令和中介者模式

    在本文中,我将解释命令模式,以及如何利用基于命令模式的第三方库来实现它们,以及如何在ASP.NET Core中使用它来解决我们的问题并使代码简洁。因此,我们将通...

    依乐祝
  • 1.2D小游戏开发实记-群英争霸

    4.清空Trigger 在idle状态中AddBehavior,进入idle状态重置atk的trigger

    祝你万事顺利
  • Unity Inspector面板常用的属性

    其它还有诸如 HelpURL 等,详情可参考 官方帮忙文档 https://docs.unity3d.com/ScriptReference/HeaderAtt...

    meteoric
  • quartz.net插件类库封装(含源码)

    1、前言    最近项目需要做一写任务作业调度的工作,最终选择了quartz.net这个插件,它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而 ...

    kmonkey
  • [享学Netflix] 十、Archaius对Commons Configuration核心API Configuration的扩展实现

    上篇文章体验了一把Netflix Archaius的使用,感受到了它对配置管理上的便捷性。或许有小伙伴会说,配置管理上它和Apache Commons Conf...

    YourBatman

扫码关注云+社区

领取腾讯云代金券