责任链模式(Chain of Responsibility)定义:
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
责任链类图:
适用场景:
1、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
2、一个请求可能需要同时被多个对象以固定的顺序处理。比如在论坛中发布一条消息,需要经过后台的一系列的处理,假设是表情图像转换->字体敏感字筛选->字体转换等。
责任链的好处:
发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。提高系统的灵活性和可扩展行。
当客户提交一个请求时,请求是沿着链传递直至有一个ConcreteHandler对象负责处理它,请求者不用管哪个对象来处理,反正该请求会被处理就可以了。这使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是责任链可简化对象的互相连接,它们仅需保持一个指向其后续的引用,而不需要它所有的候选接受者的引用。 我们可以随时增加或者修改处理一个请求的结构。增强了对象指派责任的灵活性。
当客户提交一个请求时,请求是沿着链传递直至有一个ConcreteHandler对象负责处理它,请求者不用管哪个对象来处理,反正该请求会被处理就可以了。这使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是责任链可简化对象的互相连接,它们仅需保持一个指向其后续的引用,而不需要它所有的候选接受者的引用。 我们可以随时增加或者修改处理一个请求的结构。增强了对象指派责任的灵活性。
责任链例子:
小红申请请假或者加薪,组长对2天以内的请假有权限批准,不然就提交给上级;经理对5天以内的请假有权限批准,不然就继续提交给上级;公司老总对请假不管几天都有权限批准,对500块以内的加薪也有权限,其他请求会驳回。
Handler抽象类:
abstract public class Handler {
public Request request;
private Handler next;
public Handler(Request request){
this.request=request;
}
public void setNext(Handler handler){
this.next=handler;
}
abstract boolean isMyResponse();
abstract void deal();
public void Handle(){
if(isMyResponse()){//如果是我的责任我就处理
this.deal();
}else{
if(this.next!=null){//不然就转到next
this.next.Handle();
}else{
System.out.println("对不起,没有权限处理!");
return;
}
}
}
}
具体的handler之小组长:
public class TeamLeaderHandler extends Handler {
public TeamLeaderHandler(Request request){
super(request);
}
@Override
boolean isMyResponse() {
if(request.getRequestType().equals("请假") && request.getRequestNum()<=2){
return true;
}else{
return false;
}
}
@Override
void deal() {
System.out.println("小组长同意请假");
}
}
具体的handler之经理:
public class ManagerHandler extends Handler {
public ManagerHandler(Request request){
super(request);
}
@Override
boolean isMyResponse() {
if(request.getRequestType().equals("请假")&& request.getRequestNum()<=5){
return true;
}else{
return false;
}
}
@Override
void deal() {
System.out.println("经理同意请假");
}
}
具体的handler之boss:
public class CEOHandler extends Handler {
public CEOHandler(Request request){
super(request);
}
@Override
boolean isMyResponse() {
if(request.getRequestType().equals("请假")){
return true;
}else if(request.getRequestType().equals("加薪")&& request.getRequestNum()<=500){
return true;
}else{
return false;
}
}
@Override
void deal() {
System.out.println("CEO同意加薪!");
}
}
请求类:
public class Request {
public String requestType;
public int requestNum;
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public int getRequestNum() {
return requestNum;
}
public void setRequestNum(int requestNum) {
this.requestNum = requestNum;
}
}
链条入口类:
public class LinkedEntry {
Handler entry;
public LinkedEntry(Request request){
entry=new TeamLeaderHandler(request);
ManagerHandler managerHandler=new ManagerHandler(request);
CEOHandler ceoHandler=new CEOHandler(request);
entry.setNext(managerHandler);
managerHandler.setNext(ceoHandler);
}
public void Handler(){
entry.Handle();
}
}
Client 类:
public class Client {
public static void main(String[] args) {
Request r1=new Request();
r1.setRequestType("请假");
r1.setRequestNum(1);
LinkedEntry linkedEntry=new LinkedEntry(r1);
linkedEntry.Handler();
Request r2=new Request();
r2.setRequestType("请假");
r2.setRequestNum(4);
LinkedEntry linkedEntry2=new LinkedEntry(r2);
linkedEntry2.Handler();
Request r3=new Request();
r3.setRequestType("加薪");
r3.setRequestNum(500);
LinkedEntry linkedEntry3=new LinkedEntry(r3);
linkedEntry3.Handler();
Request r4=new Request();
r4.setRequestType("加薪");
r4.setRequestNum(1000);
LinkedEntry linkedEntry4=new LinkedEntry(r4);
linkedEntry4.Handler();
}
}
测试结果: