用Unity写设计模式-责任链模式

责任链模式介绍

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

参与此模式的类和对象是:

  • Handler 处理器 (Approver 审批人)

定义了一个处理请求的接口
(可选)实现后续链接

  • ConcreteHandler(主管,副总裁,总裁 Director, VicePresident, President)

处理它负责的请求
可以访问它的后继对象
如果ConcreteHandler可以处理请求,它就这样做; 否则,它将请求转发给它的后继程序

  • Client 客户机(ChainApp)

向链上的ConcreteHandler对象发起请求

责任链模式

看完真心来一句,妙啊!

using UnityEngine;
using System.Collections;

public class ChainOfResponsibilityStructure : MonoBehaviour
{
    void Start()
    { 
        // Setup Chain of Responsibility
        Handler h1 = new ConcreteHandler1();
        Handler h2 = new ConcreteHandler2();
        Handler h3 = new ConcreteHandler3();
        h1.SetSuccessor(h2);
        h2.SetSuccessor(h3);
 
        // Generate and process request
        int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
        foreach (int request in requests)
        {
            h1.HandleRequest(request);
        }

    }
  }
 
/// <summary>
/// The 'Handler' abstract class
/// </summary>
abstract class Handler
{
    protected Handler successor;

    public void SetSuccessor(Handler successor)
    {
        this.successor = successor;
    }

    public abstract void HandleRequest(int request);
}

/// <summary>
/// The 'ConcreteHandler1' class
/// </summary>
class ConcreteHandler1 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request >= 0 && request < 10)
        {
            Debug.Log(this.GetType().Name + " handled request " + request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
    }
}

/// <summary>
/// The 'ConcreteHandler2' class
/// </summary>
class ConcreteHandler2 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request >= 10 && request < 20)
        {
            Debug.Log(this.GetType().Name + " handled request " + request);
        }
        else if (successor != null)
        {
        	//request = 14 --> h2.HandleRequest();
            //request = 22 --> h2.HandleRequest();
            //h2:
            //22 --> h3.HandleRequest();
            successor.HandleRequest(request);
        }
    }
}

/// <summary>
/// The 'ConcreteHandler3' class
/// </summary>
class ConcreteHandler3 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request >= 20 && request < 30)
        {
            Debug.Log(this.GetType().Name+" handled request "+request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
    }
}
  • 结果按顺序输出,h1无法处理的请求会传递到h2,h2无法处理的请求会传递到h3,直到被处理。
  • 就像钉钉的一条请求,等待领导审批。
    在这里插入图片描述

责任链模式案例1

//这个真实世界的代码演示了责任链模式,
//其中几个链接  
//经理和主管可以对购买请求作出回应,也可以将其转交给上级。  
//每个职位可以有自己的一套规则,他们可以批准命令。  


using UnityEngine;
using System.Collections;

namespace ChainOfResponsibilityExample1
{ 
    public class ChainOfResponsibilityExample1 : MonoBehaviour
    {
	    void Start ( )
        {
            // Setup Chain of Responsibility
            Approver larry = new Director();
            Approver sam = new VicePresident();
            Approver tammy = new President();

            larry.SetSuccessor(sam);
            sam.SetSuccessor(tammy);

            // Generate and process purchase requests
            Purchase p = new Purchase(2034, 350.00, "Assets");
            larry.ProcessRequest(p);

            p = new Purchase(2035, 32590.10, "Project X");
            larry.ProcessRequest(p);

            p = new Purchase(2036, 122100.00, "Project Y");
            larry.ProcessRequest(p);

        }
    }

    /// <summary>
    /// The 'Handler' abstract class
    /// </summary>
    abstract class Approver
    {
        protected Approver successor;

        public void SetSuccessor(Approver successor)
        {
            this.successor = successor;
        }

        public abstract void ProcessRequest(Purchase purchase);
    }

    /// <summary>
    /// 主管 处理1w以下的审批
    /// </summary>
    class Director : Approver
    {
        public override void ProcessRequest(Purchase purchase)
        {
            if (purchase.Amount < 10000.0)
            {
                Debug.Log(this.GetType().Name+" approved request# "+purchase.Number);
            }
            else if (successor != null)
            {
                successor.ProcessRequest(purchase);
            }
        }
    }

    /// <summary>
    /// 副总裁 处理2.5w以下的审批
    /// </summary>
    class VicePresident : Approver
    {
        public override void ProcessRequest(Purchase purchase)
        {
            if (purchase.Amount < 25000.0)
            {
                Debug.Log(this.GetType().Name + " approved request# " + purchase.Number);
            }
            else if (successor != null)
            {
                successor.ProcessRequest(purchase);
            }
        }
    }

    /// <summary>
    /// 总裁 处理公司承受能力的审批 10w
    /// </summary>
    class President : Approver
    {
        public override void ProcessRequest(Purchase purchase)
        {
            if (purchase.Amount < 100000.0)
            {
                Debug.Log(this.GetType().Name + " approved request# " + purchase.Number);
            }
            else
            {
                //总裁职位最高,请求终止传递。
                Debug.Log("Request# "+purchase.Number+ "requires an executive meeting!");
            }
        }
    }

    /// <summary>
    /// Class holding request details
    /// </summary>
    class Purchase
    {
        private int _number;
        private double _amount;
        private string _purpose;

        // Constructor
        public Purchase(int number, double amount, string purpose)
        {
            this._number = number;
            this._amount = amount;
            this._purpose = purpose;
        }

        // Gets or sets purchase number
        public int Number
        {
            get { return _number; }
            set { _number = value; }
        }

        // Gets or sets purchase amount
        public double Amount
        {
            get { return _amount; }
            set { _amount = value; }
        }

        // Gets or sets purchase purpose
        public string Purpose
        {
            get { return _purpose; }
            set { _purpose = value; }
        }
    }
}

责任链模式案例2

using UnityEngine;
using System.Collections;

public class ChainOfResponsibilityExample2 : MonoBehaviour
{


	void Start ( )
	{
		// 创建彼此链接的计算对象在很短时间内
		Chain calc1 = new AddNumbers();
		Chain calc2 = new SubstractNumbers();
		Chain calc3 = new DivideNumbers();
		Chain calc4 = new MultiplyNumbers();

		//现在已经进行链接
		calc1.SetNextChain(calc2);
		calc2.SetNextChain(calc3);
		calc3.SetNextChain(calc4);

		// 这是将被传递给链对象的请求,以让它们找出哪个计算对象适合该请求  
		//请求这里是我们添加的CalculationType枚举。所以我们想要添加这对数字  
		Numbers myNumbers = new Numbers(3, 5, CalculationType.Add);
		calc1.Calculate(myNumbers);

		// 其他示例:
		Numbers myOtherNumbers = new Numbers(6, 2, CalculationType.Multiply);
		calc1.Calculate(myOtherNumbers);

		// 或者将它传递给一些链对象,在这种情况下不会工作:  
		Numbers myLastNumbers = new Numbers(12, 3, CalculationType.Substract);
		calc3.Calculate(myLastNumbers);
	}

	// 只是定义了一些我们想要实现的计算类型  
	// 它比传递字符串值作为请求更好,因为这样你就不会冒任何输入错误的风险 :)
	public enum CalculationType
	{
		Add,
		Substract,
		Divide,
		Multiply
	};




	// 我们使用这个对象作为一个示例对象传递给计算链;-)  
	//找出我们想要做什么(它存储在CalculationType/calculationWanted中)  
	public class Numbers
	{
		// some numbers:
		public int number1 { get; protected set; }
		public int number2 { get; protected set; }

		// 在这里,我们存储在这个对象中,我们想做什么,让链找出谁是负责它;-)  
		public CalculationType calculationWanted { get; protected set; }

		// constructor:
		public Numbers(int num1, int num2, CalculationType calcWanted)
		{
			this.number1 = num1;
			this.number2 = num2;
			this.calculationWanted = calcWanted;
		}
	}


	// 当然不需要被称为链;-)
	public interface Chain
	{
		void SetNextChain(Chain nextChain); // 当计算失败时被调用
		void Calculate(Numbers numbers); // 尝试计算
	}


	public class AddNumbers : Chain
	{
		// 每个链对象存储一个私有的nextInChain对象,当方法calculate失败时将调用该对象  
		protected Chain nextInChain;

		public void SetNextChain(Chain nextChain)
		{
			this.nextInChain = nextChain;
		}

		public void Calculate(Numbers request)
		{
			if(request.calculationWanted == CalculationType.Add)
			{
				Debug.Log("Adding: " + request.number1 + " + " + request.number2 + " = " + (request.number1 + request.number2).ToString());
			}
			else if(nextInChain != null)
				nextInChain.Calculate(request);
			else
				Debug.Log ("Handling of request failed: " + request.calculationWanted);
		}
	}

	public class SubstractNumbers : Chain
	{
		protected Chain nextInChain;

		public void SetNextChain(Chain nextChain)
		{
			this.nextInChain = nextChain;
		}

		public void Calculate(Numbers request)
		{
			if(request.calculationWanted == CalculationType.Substract)
			{
				Debug.Log("Substracting: " + request.number1 + " - " + request.number2 + " = " + (request.number1 - request.number2).ToString());
			}
			else if(nextInChain != null)
				nextInChain.Calculate(request);
			else
				Debug.Log ("Handling of request failed: " + request.calculationWanted);
		}
	}
	
	public class DivideNumbers : Chain
	{
		protected Chain nextInChain;
		
		public void SetNextChain(Chain nextChain)
		{
			this.nextInChain = nextChain;
		}
		
		public void Calculate(Numbers request)
		{
			if(request.calculationWanted == CalculationType.Divide)
			{
				Debug.Log("Dividing: " + request.number1 + " / " + request.number2 + " = " + (request.number1 / request.number2).ToString());
			}
			else if(nextInChain != null)
				nextInChain.Calculate(request);
			else
				Debug.Log ("Handling of request failed: " + request.calculationWanted);
		}
	}
	
	public class MultiplyNumbers : Chain
	{
		protected Chain nextInChain;
		
		public void SetNextChain(Chain nextChain)
		{
			this.nextInChain = nextChain;
		}
		
		public void Calculate(Numbers request)
		{
			if(request.calculationWanted == CalculationType.Multiply)
			{
				Debug.Log("Multiplying: " + request.number1 + " * " + request.number2 + " = " + (request.number1 * request.number2).ToString());
			}
			else if(nextInChain != null)
				nextInChain.Calculate(request);
			else
				Debug.Log ("Handling of request failed: " + request.calculationWanted);
		}
	}

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值