简介
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
书中实例
青涩的小菜实习期结束了,面临转正的他打算让领导给他加些薪水,他找到部门经理,经理肯定他的业绩但说加薪不在我的职责范围,我向上级总监请示,总监听说后说加薪也不在我的职责范围,我要向上级请示,总经理知道这件事,但他并不了解小菜,也不清楚他的能力,以大学生基数大理由拒绝了加薪,让小菜再多“沉淀沉淀”。在一旁的大鸟听后,拍了拍小菜的肩膀,再沉淀沉淀吧,不过今天的这件事也蕴藏了一项设计模式,我们用代码来把它写下来。
职责链模式实现程序
//申请
class Request
{
//申请类别
private string requestType;
public string RequestType
{
get { return requestType; }
set { requestType = value; }
}
//申请内容
private string requestContext;
public string RequestContent
{
get { return requestContext; }
set { requestContext = value; }
}
//数量
private int number;
public int Number
{
get { return number; }
set { number = value; }
}
}
//管理者
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 Program
{
static void Main(string[] args)
{
CommonManager jinli = new CommonManager("金利");
Majordomo zongjian = new Majordomo("宗剑");
GeneralManager zongjingli = new GeneralManager("钟精励");
jinli.SetSuperior(zongjian);
zongjian.SetSuperior(zongjingli);
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.Read();
}
}
组成类图
关系介绍
处理者类(Handler)是具体处理者类(ConcreteHandler)的父类,客户端(Client)可对其进行调用
职责链模式的构成
Handler(处理者):定义一个处理请示接口
ConcreteHandler(具体处理者):处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之,否则就将该请求转发给它的后继者
职责链模式的优点
1.当客户提交一个请求时,请求是沿链传递直至有一个具体处理者对象对其负责处理它。
2.可以随时增加或修改处理一个请求的结构,增强给对象指派职责的灵活性
使用场景
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。