一,定义
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
二,示例
实现一个加薪层层审批的例子
/**
* @类描述:申请
*/
public class Request {
private String requestType; //请求类型
private String requestContent; //请求内容
private int number; //请求数量
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public String getRequestContent() {
return requestContent;
}
public void setRequestContent(String requestContent) {
this.requestContent = requestContent;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
/**
* @类描述:管理者类
*/
public abstract class Manager {
protected String name; //管理者名字
protected Manager superior; //管理者上级
public Manager(String name){
this.name = name;
}
public void setSuperior(Manager manager){
this.superior = manager;
}
public abstract void requestApplication(Request request); //申请请求
}
/**
* @类描述:经理
*/
public class CommonManager extends Manager{
public CommonManager(String name) {
super(name);
}
@Override
public void requestApplication(Request request) {
if (request.getRequestType().equals("请假") && request.getNumber() <= 2){
System.out.println(name + ":" + request.getRequestContent() + ",数量:" + request.getNumber() + ",被批准!");
} else {
if (null != superior){
superior.requestApplication(request);
}
}
}
}
package com.xp.design.responsibility;
/**
* @类描述:总监
*/
public class MajordomoManager extends Manager{
public MajordomoManager(String name) {
super(name);
}
@Override
public void requestApplication(Request request) {
if (request.getRequestType().equals("请假") && request.getNumber() <= 5){
System.out.println(name + ":" + request.getRequestContent() + ",数量:" + request.getNumber() + ",被批准!");
} else {
if (null != superior){
superior.requestApplication(request);
}
}
}
}
package com.xp.design.responsibility;
/**
* @类描述:总经理
* @创建人:Wangxiaopan
* @创建时间:2018/6/5 0005 15:48
* @修改人:
* @修改时间:2018/6/5 0005 15:48
* @修改备注:
*/
public class GeneralManager extends Manager {
public GeneralManager(String name) {
super(name);
}
@Override
public void requestApplication(Request request) {
if (request.getRequestType().equals("请假")) {
System.out.println(name + ":" + request.getRequestContent() + ",数量:" + request.getNumber() + ",被批准!");
} else if (request.getRequestType().equals("加薪") && request.getNumber() <= 500) {
System.out.println(name + ":" + request.getRequestContent() + ",数量:" + request.getNumber() + ",被批准!");
} else if (request.getRequestType().equals("加薪") && request.getNumber() > 500) {
System.out.println(name + ":" + request.getRequestContent() + ",数量:" + request.getNumber() + ",再说吧!");
}
}
}
//test main
//职责链模式
public static void responsibilityModel(){
CommonManager jingli = new CommonManager("经理");
MajordomoManager zongjian = new MajordomoManager("总监");
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 request1 = new Request();
request1.setRequestType("请假");
request1.setRequestContent("小菜请假");
request1.setNumber(4);
jingli.requestApplication(request1);
Request request2 = new Request();
request2.setRequestType("加薪");
request2.setRequestContent("小菜加薪");
request2.setNumber(500);
jingli.requestApplication(request2);
Request request3 = new Request();
request3.setRequestType("加薪");
request3.setRequestContent("小菜加薪");
request3.setNumber(1000);
jingli.requestApplication(request3);
}
输出结果:
经理:小菜请假,数量:1,被批准!
总监:小菜请假,数量:4,被批准!
总经理:小菜加薪,数量:500,被批准!
总经理:小菜加薪,数量:1000,再说吧!
三,总结
优点:
- 当客户提交一个请求时,请求时沿链传递直至有一个ConcreteHandler对象负责处理它,这就使得接受者和发送者都没有对方明确的信息,且链中的对象自己并不知道链的结构,结果是职责链可简化对象的互相连接,他们仅需保持一个指向其后继者的引用,而不需要保持它所有的候选接受者的引用。
- 可以随时地增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。
缺点:
- 责任链模式与if…else…相比,他的耦合性要低一些,因为它把条件判定都分散到了各个处理类中,并且这些处理类的优先处理顺序可以随意设定。责任链模式也有缺点,这与if…else…语句的缺点是一样的,那就是在找到正确的处理类之前,所有的判定条件都要被执行一遍,当责任链比较长时,性能问题比较严重。
适用场景:
- 就像开始的例子那样,假如使用if…else…语句来组织一个责任链时感到力不从心,代码看上去很糟糕时,就可以使用责任链模式来进行重构。
参考:《大化设计模式》