博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式(十四)—— 职责链模式
阅读量:5308 次
发布时间:2019-06-14

本文共 4031 字,大约阅读时间需要 13 分钟。

模式简介


使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一个链,并沿着链传递该请求,直到有一个对象处理它为止。

职责链模式是一种行为型模式,它包括命令对象以及一系列处理对象。每个处理对象决定它能够处理哪些命令对象,将不能处理的命令对象传递至职责链中的下一个处理对象。

想象一下公司的OA系统,提交请假单时系统会根据你的请假天数将申请单"交给"不同的人去审批,例如请假1-2天,只需要Team Leader审批,3-5天需要Manager审批,大于5天需要Director审批,这就形成了一个职责链。假如你要请假1个月,系统首先把请求传递给Leader对象,Leader对象发现自己无法处理这个请求,将请求传递给Manager对象,Manager也无法处理,再传递给Director。

971601-20180622145636903-705544470.png

结构说明


971601-20180622100558236-1371907805.png

角色说明

  • Handler

定义一个处理请求的接口。

  • ConcreteHandler

实际负责处理请求的类。如果符合条件,处理该请求,否则转发给后续的ConcreteHandler。

结构代码

声明抽象类Handler,定义一个处理请求的接口。

public abstract class Handler{    protected Handler _successor;    public void SetSuccessor(Handler successor)    {        this._successor = successor;    }    public abstract void Handle(int request);}

具体实现类,负责处理请求。ConcreteHanlder1处理reqeust小于等于10的请求,其他由ConcreteHandler2进行处理。

class ConcreteHandler1 : Handler{    public override void Handle(int request)    {        if (request <= 10)        {            Console.WriteLine($"{this.GetType().Name} handled request {request}");        }        else if (_successor != null)        {            _successor.Handle(request);        }    }}class ConcreteHandler2 : Handler{    public override void Handle(int request)    {        if (request > 10)        {            Console.WriteLine($"{this.GetType().Name} handled request {request}");        }        else if (_successor != null)        {            _successor.Handle(request);        }    }}

客户端调用,设置职责链h1 -> h2,依次对requests数组中的元素进行处理。

class Program{    static void Main(string[] args)    {        ConcreteHandler1 h1 = new ConcreteHandler1();        ConcreteHandler2 h2 = new ConcreteHandler2();        h1.SetSuccessor(h2);        int[] requests = { 1, 4, 5, 11, 24 };        foreach (var request in requests)        {            h1.Handle(request);        }        Console.ReadLine();    }}

输出结果:

971601-20180622104205532-331220540.png

工作原理

当用户提交一个请求,请求将沿着职责链依次传递知道有一个ConcreteHandler对象负责处理它。

971601-20180622132342434-288934607.png

示例分析


回到本篇开头请假申请的示例,本节我们将通过职责链模式来实现它,首先创建请求类LeaveReqeust,包含申请人以及申请天数,

class LeaveRequest{    public string Applicant { get; set; }    public int Days { get; set; }}

声明抽象类Approver,定义一个处理请求的抽象方法Approve。

abstract class Approver{    protected Approver _successor;    public void SetSuccessor(Approver successor)    {        _successor = successor;    }    public abstract void Approve(LeaveRequest request);}

声明Leader、Manager、Director三个实际处理请求的类。

class Leader : Approver{    public override void Approve(LeaveRequest request)    {        if (request.Days <= 2)        {            Console.WriteLine($"{this.GetType().Name} approved request {request.Applicant},{request.Days}");        }        else if (_successor != null)        {            _successor.Approve(request);        }    }}class Manager : Approver{    public override void Approve(LeaveRequest request)    {        if (request.Days <= 5)        {            Console.WriteLine($"{this.GetType().Name} approved request {request.Applicant},{request.Days}");        }        else if (_successor != null)        {            _successor.Approve(request);        }    }}class Director : Approver{    public override void Approve(LeaveRequest request)    {        Console.WriteLine($"{this.GetType().Name} approved request {request.Applicant},{request.Days}");    }}

客户端调用,创建职责链leader->manager->director,接着创建3个请求传递给职责链,依次处理。

class Program{    static void Main(string[] args)    {        Leader leader = new Leader();        Manager manager = new Manager();        Director director = new Director();        leader.SetSuccessor(manager);        manager.SetSuccessor(director);        LeaveRequest jack = new LeaveRequest        {            Applicant = "Jack",            Days = 2        };        LeaveRequest tom = new LeaveRequest        {            Applicant = "Tom",            Days = 30        };        LeaveRequest mike = new LeaveRequest        {            Applicant = "Mike",            Days = 4        };        leader.Approve(jack);        leader.Approve(tom);        leader.Approve(mike);        Console.ReadLine();    }}

输出结果:

971601-20180622151654482-138693015.png

适用场景


  • 由多个对象处理一个请求,在运行时确定具体使哪个对象进行处理

  • 职责链可以动态指定

转载于:https://www.cnblogs.com/Answer-Geng/p/9213010.html

你可能感兴趣的文章
vim中文帮助教程
查看>>
Android 创建与解析XML(四)—— Pull方式
查看>>
CodeForces 411B 手速题
查看>>
同比和环比
查看>>
美国在抛弃慕课,中国却趋之若鹜
查看>>
SpringMvc拦截器运行原理。
查看>>
MySQL基础3
查看>>
云计算数据与信息安全防护
查看>>
全局设置导航栏
查看>>
RxJS & Angular
查看>>
面向对象(多异常的声明与处理)
查看>>
MTK笔记
查看>>
ERROR: duplicate key value violates unique constraint "xxx"
查看>>
激活office 365 的启动文件
查看>>
9款免费的Windows远程协助软件
查看>>
Maven(八) Maven项目和testng结合应用
查看>>
iOS 的 set.get.构造方法
查看>>
无法根据中文查找
查看>>
文件编码,文件或文件名编码格式转换(转)
查看>>
[简讯]phpMyAdmin项目已迁移至GitHub
查看>>