设计模式之责任链

简介: 设计模式之责任链

责任链模式介绍


56961977467644378014214625b16735~tplv-k3u1fbpfcp-zoom-1.png


任链模式是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。


责任链模式的核心是解决一组服务中的先后执行处理关系。


责任链模式可以让各个服务模块更加清晰,而每一个模块可以通过next的方式进行获取。而每一个next是由继承的统一抽象类实现的,最终所有类的职责可以动态的进行编排使用,编排的过程可以做成可配置化。


在使用责任链时,如果场景比较固定,可写死到代码中进行初始化。但如果业务场景经常变化可以做成xml配置的方式进行处理,也可以保存到数据库中进行初始化操作。


实际的业务中在使用责任链时会进行一系列的包装,通过把不同的责任节点进行组装,构成一条完整业务的责任链。


责任链模式很好的处理单一职责和开闭原则,简单耦合也使对象关系更加清晰,而且外部的调用方并不需要关系责任链是如何处理的。



责任链模式结构


  • 处理者


声明了所有具体处理者的通用接口,该接口通常仅包含单个方法用于请求处理,但有时其还会包含一个设置链上下处理者的方法。


  • 基础处理者

是一个可选的类,你可以将所有处理者共用的样本代码放置在其中。(通常情况下,该类定义了一个保存对于下个处理者引用的成员变量。客户端可通过将处理者的构造函数或设定方法来创建链。该类还可以实现默认的处理行为,确定下个处理者存在后再将请求传递给它。)


  • 具体处理者


包含处理请求的实际代码。每个处理者接收到请求后,都必须决定是否进行处理,或者说是否沿着链传递请求。


  • 客户端


可根据程序逻辑一次性或者动态的生成链。



适用场景


  • 当程序需要使用不同方式处理不同种类请求,而且请求类型和顺序预先未知时。


  • 业务逻辑必须按顺序执行多个处理者时。


  • 处理者及其顺序必须在运行时进行改变,可以使用责任链模式。


实现方式


  • 声明处理者接口并描述请求处理方法的签名


  • 可以根据处理者接口创建抽象处理者基类(需要一个成员变量来存储指向链上下个处理者的引用)


  • 创建具体的处理者子类并实现其处理方法。(每个处理者在接收到请求后都必须做两个决定:1、是否自行处理请求;2、是否将该请求沿着链进行传递。)


  • 客户端可自行组装链,或者从其他对象处获得预先组装好的链。


  • 客户端可触发链中的任意处理者,而不仅仅是第一个。请求将通过链进行传递,直至某个处理者拒绝继续传递或者请求到达链尾。


Demo


责任链模式在C#程序中并不常见,因为它仅在代码与对象链打交道时才能发货作用。


处理者接口


    /// <summary>
    /// 处理者接口
    /// </summary>
    public interface IHandler 
    {
        IHandler SetNext(IHandler handler);
        object Handle(object request);
    }



抽象类

    /// <summary>
    /// 抽象类
    /// </summary>
    public abstract class AbstractHandler :IHandler
    {
        private IHandler _nextHandler;
        public IHandler SetNext(IHandler handler)
        {
            this._nextHandler = handler;
            return handler;
        }
        /// <summary>
        /// 虚方法,在子类继承中需实现此方法。
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public virtual  object Handle(object request)
        {
            if (this._nextHandler !=null)
            {
                return this._nextHandler.Handle(request);
            }
            else
            {
                return null;
            }
        }
    }



实现抽象类

  /// <summary>
    /// 猴子类
    /// </summary>
    public class MonkeyHandler : AbstractHandler
    {
        public override object Handle(object request)
        {
            if ((request as string)=="猴子")
            {
                return "在猴子类中"+request.ToString();
            }
            else
            {
                return base.Handle(request);                        //父类中的Handle方法        
            }
        }
    }
    /// <summary>
    /// 松鼠类
    /// </summary>
    public class SquirreHandler : AbstractHandler
    {
        public override object Handle(object request)
        {
            if ((request as string) == "松鼠")
            {
                return "在松鼠类中" + request.ToString();
            }
            else
            {
                return base.Handle(request);                        //父类中的Handle方法        
            }
        }
    }
    /// <summary>
    /// 小狗类
    /// </summary>
    public class DogHandler : AbstractHandler
    {
        public override object Handle(object request)
        {
            if ((request as string) == "小狗")
            {
                return "在小狗类中" + request.ToString();
            }
            else
            {
                return base.Handle(request);                        //父类中的Handle方法        
            }
        }
    }    


客户端和Main()验证


 class Client 
    {
        public static void ClientCode(AbstractHandler handler) 
        {
            foreach (var item in new List<string>{"松鼠","猴子","人"})
            {
                Console.WriteLine("到底是谁:"+item);
                var result = handler.Handle(item);
                if (result!=null)
                {
                    Console.WriteLine("谁:"+result);
                }
                else
                {
                    Console.WriteLine("No Find");
                }
            }
            Console.WriteLine("开始");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var monkey = new MonkeyHandler();
            var squirrel = new SquirreHandler();
            var dog = new DogHandler();
            monkey.SetNext(squirrel).SetNext(dog);      //构建链条
            Console.WriteLine("----------第一次");
            Client.ClientCode(monkey);
            Console.WriteLine();
            Console.WriteLine("第二次");
            Client.ClientCode(squirrel);
            Console.WriteLine("第三次");
            Client.ClientCode(dog);
            Console.ReadKey();
        }
    }


2c22488a63d04e4ab92566ad62a5e537~tplv-k3u1fbpfcp-zoom-1.png


可以通过上面图片标红的地方了解到具体输出的值,第一次(初始位置)时在最后狗类处不继续执行,第二次(中间位置)在猴子类处不执行,第三次所有的都不执行(第三次到链尾了)。



目录
相关文章
|
6月前
|
设计模式 Java
常用设计模式(工厂方法,抽象工厂,责任链,装饰器模式)
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法,观察者模式,策略模式)
60 2
|
2月前
|
设计模式 存储 算法
设计模式——责任链
OA系统的采购审批项目、职责链模式基本介绍、职责链模式解决 OA 系统采购审批项目
设计模式——责任链
|
6月前
|
设计模式 安全 Java
设计模式之责任链 Chain Of Responsibility
设计模式之责任链 Chain Of Responsibility
40 1
|
6月前
|
设计模式
【设计模式】张一鸣笔记:责任链接模式怎么用?
【设计模式】张一鸣笔记:责任链接模式怎么用?
44 1
|
6月前
|
设计模式 Java Spring
责任链设计模式详解
该内容主要介绍了如何使用Java实现责任链模式。
61 4
|
6月前
|
设计模式 算法 调度
行为型设计模式:模板设计模式/观察者设计模式/策略设计模式/责任链设计模式
行为型设计模式:模板设计模式/观察者设计模式/策略设计模式/责任链设计模式
55 0
|
6月前
|
设计模式
二十三种设计模式全面解析-职责链模式(Chain of Responsibility Pattern):解放代码责任链,提升灵活性与可维护性
二十三种设计模式全面解析-职责链模式(Chain of Responsibility Pattern):解放代码责任链,提升灵活性与可维护性
|
设计模式 Java 数据库连接
JAVA设计模式8:装饰模式,动态地将责任附加到对象上,扩展对象的功能
JAVA设计模式8:装饰模式,动态地将责任附加到对象上,扩展对象的功能
|
设计模式 前端开发 数据安全/隐私保护
前端通用编程基础的设计模式之责任链
在前端开发中,我们常常需要处理一些复杂的业务逻辑,例如表单验证、权限控制等。这些业务逻辑可能需要经过多个步骤才能完成,每个步骤都需要进行具体的处理和判断。这时候就需要使用责任链模式来实现业务逻辑的流程化和扩展性。
135 0
|
设计模式 分布式计算 大数据
大数据开发基础的设计模式的责任链
当涉及大数据的开发时,设计模式是至关重要的。其中一种常见的设计模式是责任链模式,它可以有效地处理多个对象之间的请求。
90 0