职责链模式
定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
解决
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。在处理消息的时候以过滤很多道。
职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
优点
- 当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,他们仅需保持一个指向后继者的引用,而不需要保持它所有的候选接收者的引用。降低耦合度。
- 可以随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。
- 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
缺点
- 不能保证请求一定被接收。
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
- 可能不容易观察运行时的特征,有碍于除错。
结构
职责链模式包含如下角色:
- Handler: 处理者接口类
- ConcreteHandler: 具体处理者类
实现
package chainOfResponsibility;
abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor)
{
this.successor=successor;
}
public abstract void handleRequest(int request);
}
// 具体处理者类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,则处理,否则转给它的后继者处理
class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 0 && request <= 10) {
System.out.println(this.getClass().getName() + "处理了请求" + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request > 10 && request <= 20) {
System.out.println(this.getClass().getName() + "处理了请求" + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int request) {
if (request > 20 && request <= 30) {
System.out.println(this.getClass().getName() + "处理了请求" + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
package chainOfResponsibility;
public class chainORClient {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();
handlerA.setSuccessor(handlerB);
handlerB.setSuccessor(handlerC);
int[] requests = { 2, 14, 5, 6, 8, 23, 12, 21 };
for (int i : requests) {
handlerA.handleRequest(i);
}
}
}
实例
package chainOfResponsibility.demo;
public 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 requestApplication(Request request);
}
//经理
class CommonManager extends Manager
{
public CommonManager(String name) {
super(name);
}
@Override
public void requestApplication(Request request) {
if(request.getRequestType()=="请假"&&request.getNumber()<=2)
{
//经理只能给两天假
System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"被批准");
}
else
{
//其余转到上级
if(superior!=null)
superior.requestApplication(request);
}
}
}
//总监
class Majordomo extends Manager
{
public Majordomo(String name) {
super(name);
}
@Override
public void requestApplication(Request request) {
if(request.getRequestType()=="请假"&&request.getNumber()<=5)
{
//经理只能给一周假
System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"被批准");
}
else
{
//其余转到上级
if(superior!=null)
superior.requestApplication(request);
}
}
}
//总经理
class GeneralManager extends Manager
{
public GeneralManager(String name) {
super(name);
}
@Override
public void requestApplication(Request request) {
if(request.getRequestType()=="请假"&&request.getNumber()<=5)
{
//经理只能给一周假
System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"被批准");
}
else if (request.getRequestType()=="加薪"&&request.getNumber()<=500) {
//加薪500内可以
System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"被批准");
}
else if(request.getRequestType()=="加薪"&& request.getNumber()>500)
{
System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"不行");
}
}
}
package chainOfResponsibility.demo;
public class chainORClient {
public static void main(String[] args) {
CommonManager jingli =new CommonManager("王经理");
Majordomo zongjian = new Majordomo("王总监");
GeneralManager zongjingli =new GeneralManager("王总经理");
jingli.setSuperior(zongjian);
zongjian.setSuperior(zongjingli);
Request request=new Request();
request.setRequestType("请假");
request.setRequestContent("我要请假");
request.setNumber(1);
jingli.requestApplication(request);
Request request2=new Request();
request2.setRequestType("请假");
request2.setRequestContent("我要请假");
request2.setNumber(4);
//也是jingli发起的,但实际谁决策(调用的谁)不知道
jingli.requestApplication(request2);
Request request3=new Request();
request3.setRequestType("加薪");
request3.setRequestContent("我要加薪");
request3.setNumber(500);
//也是jingli发起的,但实际谁决策(调用的谁)不知道
jingli.requestApplication(request3);
Request request4=new Request();
request4.setRequestType("加薪");
request4.setRequestContent("我要加薪");
request4.setNumber(1000);
//也是jingli发起的,但实际谁决策(调用的谁)不知道
jingli.requestApplication(request4);
}
}
总结
- 在设计职责链模式时,在客户端将每个处理者的上级设置。
- 抽象处理者的方法(设置上级)是关键。
- 在高级语言中,比如处理异常也是用职责链模式;Strust2的拦截器、JSP和Servlet的Filter等。