用心理解设计模式——责任链模式 (Chain of Responsibility Pattern)

前置文章: 设计模式的原则 

其他设计模式:用心理解设计模式

设计模式相关代码已统一放至 我的 Github

 

一、定义

  行为型模式之一。

  Avoid coupling the sender of  a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

  (通过给予多个对象处理请求的机会,来避免请求的发送方与接收方之间的耦合。将接收对象链起来,并沿着链传递请求,直到有对象处理它为止。)

二、结构解析

  责任链模式的一般结构有两种角色: 抽象处理者、具体处理者。

  抽象处理者(Handler):定义一个处理请求的接口方法,并持有一个后继责任对象(另一个处理者)。当这个接口方法被调用,并且自身不能处理时,调用后继责任对象中同样的接口方法,使得请求可以向更高的位置传递。一般可以将这个接口方法定义为 模板方法确定责任传递规则,同时为具体处理者出一个抽象的接口,让具体处理者实现自身的请求处理功能。

  具体处理者(ConcreteHandler):继承抽象处理者,实现自身的请求处理功能。

三、评价

  责任链模式让每个(最后一个没有)处理者持有另一个后继处理者,众多处理者形成了一个处理链。让请求在这个链上传递,执行时就像一个 “if, elseif..., else” 语句执行一样。

  责任链模式中各处理者常存在等级或权限元素(可能是潜在的),条件判断与这个元素密切相关。如审批流。

  责任链模式解除了请求发送者和接收者的耦合,使请求发送者不用依赖每一个接收者,想要增加请求接收者也很容易。

  应避免出现闭环链,否则可能将形成死循环(虽然闭环,但实际执行不超过一圈的,也不会死循环)。

四、实现

using UnityEngine;

namespace ChainOfResponsibility
{
    //抽象处理器
    public abstract class Handler
    {
        public string name;         //名称
        public int level;           //自身等级
        public Handler successor;   //持有一个后继责任对象(另一个处理器)

        public Handler(string name, int level, Handler successor = null)
        {
            this.name = name;
            this.level = level;
            this.successor = successor;
        }

        //定义一个模板方法,确定责任传递规则,约定一个条件,满足条件时自己处理,否则交给后继者处理。
        public void HandleRequest(int needLevel)
        {   
            if (level >= needLevel)     //处理者等级大于等于请求要求的等级时,才可处理
            {
                this.HandleImp();
            }
            else
            {
                if (successor != null)
                {
                    //交给后继者处理。
                    successor.HandleRequest(needLevel);
                }
                else
                {
                    //注意,这里要处理好,无后继者时的情况。
                    //如,只好勉强自己处理。
                    this.HandleImp();
                }
            }
        }

        public abstract void HandleImp();
    }

    //具体处理器
    public class ConcreteHandler : Handler
    {
        public ConcreteHandler(string name, int level, Handler successor = null) : base(name, level, successor) { }

        public override void HandleImp()
        {
            Debug.Log("我来处理请求,我是: " + this.name);
        }
    }

    public class Client
    {
        static public void Main()
        {
            //组装责任链
            Handler handlerA = new ConcreteHandler("ConcreteHandlerA", 9);
            Handler handlerB = new ConcreteHandler("ConcreteHandlerB", 3, handlerA);
            Handler handlerC = new ConcreteHandler("ConcreteHandlerC", 2, handlerB);
            Handler handlerD = new ConcreteHandler("ConcreteHandlerD", 1, handlerC);

            handlerD.HandleRequest(1);  //请求要求等级为1时,D就可以处理
            handlerD.HandleRequest(5);  //请求要求等级为5时,A才能处理
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NRatel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值