《设计模式学习笔记--chain of responsibility 职责链模式》由会员分享,可在线阅读,更多相关《设计模式学习笔记--chain of responsibility 职责链模式(6页珍藏版)》请在金锄头文库上搜索。
1、 职责链模式是一种对象的行为模式【GOF95 】。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。引入职责链模式的目的仍然是为了解除耦合,从“封装变化”的角度出发,它封装了“职责行为的变化”,同时又利用链结构保证了消息的传递,此模式的优势在于它能够“智能”地根据条件在职责链中定位到合适的对象,并执行其职能。职责链模式的 UML 图如下:责任链模式涉及到的角色如下所示:1、抽象处理者(Hand
2、ler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。2、具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。下面,我们还是用代码来说明。程序如下图 : 一、职责链模式的基本思路1、抽象处理者(Handler)角色:using System;using System.Collections.Generic;using System.Linq;using System.Text;na
3、mespace MyChainResponsibilityabstract class Handler/定义一个设置下一个处理者的接口protected Handler _successor;public void SetSuccessor(Handler sucessor)this._successor = sucessor;/定义一个处理信息的接口public abstract void HandleRequest(int request);2、具体处理者(ConcreteHandler)角色using System;using System.Collections.Generic;usi
4、ng System.Linq;using System.Text;namespace MyChainResponsibility第一个处理者第二个处理者第三个处理者3、客户端应用#region 基本思路示例 Console.WriteLine(-基本思路示例-);Handler h1 = new ConcreteHandlerOne();Handler h2 = new ConcreteHandlerTwo();Handler h3 = new ConcreteHandlerThree();/设置责任链h1.SetSuccessor(h2);h2.SetSuccessor(h3);int re
5、quests = 2,5,21,22,18,26,89;foreach (int request in requests)/责任处理h1.HandleRequest(request);Console.ReadKey();#endregion二、关于办公室发票报销的职责链处理模式办公室的发票,根据它们的金额大小分别由科长,处长,局长逐级负责审阅报批,职责链处理流程从科长到处长再到局长。代码如下1、抽象处理者(Handler)角色:ApproveHandler.using System;using System.Collections.Generic;using System.Linq;using
6、 System.Text;namespace MyChainResponsibilityabstract class ApproveHandler#region 职务属性private string headship;public string HeadShipget return headship; set headship = value; #endregion#region 构造函数public ApproveHandler(string HeadShip) this.headship = HeadShip;#endregion#region 设置后继者接口protected Appro
7、veHandler _successor;public void SetSuccessor(ApproveHandler successor)this._successor = successor;#endregion#region 处理职责接口public abstract void HandleRequest(Receipt request);#endregion2、具体处理者(ConcreteHandler)角色:ConcreteApproveHandlersusing System;using System.Collections.Generic;using System.Linq;u
8、sing System.Text;namespace MyChainResponsibility科长处长局长3、客户端应用Receipt 发票类定义using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyChainResponsibility #region 发票类class Receiptprivate double _amount;private string _purpose;/ 构造函数public Receipt( double amount, stri
9、ng purpose)this._amount = amount;this._purpose = purpose;#region 金额public double Amountget return _amount; set _amount = value; #endregion#region 用途public string Purposeget return _purpose; set _purpose = value; #endregion#endregion客户端应用#region 办公室报销责任链Console.WriteLine(-办公室报销责任链-);KeZhang ke = new
10、KeZhang(科长);ChuZhang chu = new ChuZhang(处长 );JuZhang ju = new JuZhang(局长);Receipt r1 = new Receipt(360, 请客吃饭 .); Receipt r2 = new Receipt(760, 处室活动开销 .);Receipt r3 = new Receipt(360, 采购办公用品 .);/设置责任链ke.SetSuccessor(chu);chu.SetSuccessor(ju);/责任处理ke.HandleRequest(r1);ke.HandleRequest(r2);ke.HandleReq
11、uest(r3);Console.ReadKey();#endregion总结1、何时采用从代码角度来说,如果一个逻辑的处理由不同责任对象完成,客户端希望能自定义这个处理流程并且不希望直接和多个责任对象发生耦合的时候可以考虑责任链模式。从应用角度来说,如果对一个事情的处理存在一个流程,需要经历不同的责任点进行处理,并且这个流程比较复杂或只希望对外公开一个流程的入口点的话可以考虑责任链模式。其实,责任链模式还可以在构架的层次进行应用,比如.NET 中的层次异常处理关系就可以看作是一种责任链模式。2、实现要点(1)有一个抽象责任角色,避免各责任类型之间发生耦合。(2)抽象责任角色中定义了后继责任角色,并对外提供一个方法供客户端配置。(3)各具体责任类型根据待处理对象的状态结合自己的责任范围来判断是否能处理对象,如果不能处理提交给上级责任人处理(也就是纯的责任模式,要么自己处理要么提交给别人)。当然,也可以在进行部分处理后再提交给上级处理(也就是不纯的责任链模式)。(4)需要在客户端链接各个责任对象,如果链接的不恰当,可能会导致部分对象不能被任何一个责任对象进行处理。3、注意事项责任链模式和状态模式的区别在于,前者注重责任的传递,并且责任链由客户端进行配置,后者注重对象状态的转换,这个转换过程对客户端是透明的。