职责链模式定义
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
模式产生的动机
以学生请假为例
模式结构UML图
角色分类:
Handler:抽象管理者,相当于所有管理者的父类,抽象出管理的总方法
ConcreteHandler:具体处理者
Client:客户端,客户的请求
模式分析:
1、在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
2、请求在这条链上传递,直到链上的某一个对象处理此请求为止
3、发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态的重新组织链和分配责任。
举例:
小菜想请求上级为他加薪和请假,需要经过经理、总监,最终由总经理决定。下面来看一下这个例子的代码。
抽象管理者,相当于Handler
//管理者
abstract class Manager
{
protected string name;
//管理者的上级
protected Manager superior;
public Manager(string name)
{
this.name = name;
}
//设置管理者的上级
public void SetSuperior(Manager superior)
{
this.superior = superior;
}
//申请请求
abstract public void RequestApplications(Request request);
}
经理类
class CommonManager:Manager
{
public CommonManager(string name) : base(name)
{ }
public override void RequestApplications(Request request)
{
if (request.RequestType == "请假" && request.Number <= 2)//经理所能有的权限就是可准许下属两天内的假期
{
Console.WriteLine("{0}:{1}数量{2}被批准", name, request.RequestContent, request.Number);
}
else
{
if(superior!=null) //其余的申请都需转到上级
{
superior.RequestApplications(request);
}
}
}
}
总监类
class Majordomo:Manager
{
public Majordomo(string name) : base(name)
{ }
public override void RequestApplications(Request request)
{
if(request.RequestType=="请假"&&request.Number<=5)
{
Console.WriteLine("{0}:{1}数量{2}被批准", name, request.RequestContent, request.Number);
}
else
{
if(superior!=null)
{
superior.RequestApplications(request);
}
}
}
}
总经理类
//总经理
class GeneralManager:Manager
{
public GeneralManager(string name):base(name)
{
}
public override void RequestApplications(Request request)
{
if (request.RequestType == "请假")
{
Console.WriteLine("{0}:{1}数量{2}被批准", name, request.RequestContent, request.Number);
}
else if(request.RequestType=="加薪"&&request.Number<=500)
{
Console.WriteLine("{0}:{1}数量{2}被批准", name, request.RequestContent, request.Number);
}
else if(request.RequestType=="加薪"&&request.Number>500)
{
Console.WriteLine("{0}:{1}数量{2}再说吧", name, request.RequestContent, request.Number);
}
}
}
申请
class Request
{
//申请类别
private string requestType;
public string RequestType
{
get { return requestType; }
set { requestType = value; }
}
//申请内容
private string requestContent;
public string RequestContent
{
get { return requestContent; }
set { requestContent = value; }
}
//数量
private int number;
public int Number
{
get { return number; }
set { number = value; }
}
}
客户端调用
CommonManager jinli = new CommonManager("金立");
Majordomo zongjian = new Majordomo("总监");
GeneralManager zhongjingli = new GeneralManager("钟经理");
//设置上级,完全根据实际情况来更改设置
jinli.SetSuperior(zongjian);
zongjian.SetSuperior(zhongjingli);
Request request = new Request();
request.RequestType = "加薪";
request.RequestContent = "小菜请假";
request.Number = 1;
jinli.RequestApplications(request);
Request request2 = new Request();
request2.RequestType = "加薪";
request2.RequestContent = "小菜请假";
request2.Number = 4;
jinli.RequestApplications(request2);
Request request3 = new Request();
request3.RequestType = "请假";
request3.RequestContent = "小菜请求加薪";
request3.Number = 500;
jinli.RequestApplications(request3);
Request request4 = new Request();
request4.RequestType = "请假";
request4.RequestContent = "小菜请求加薪";
request4.Number = 1000;
jinli.RequestApplications(request4);
Console.ReadKey();
职责链模式的优点:
1、降低耦合度
2、可简化对象的相互连接
3、增强给对象指派职责的灵活性
4、增加新的请求处理类很方便
模式使用环境
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求
3、可动态指定一组对象处理请求