设计模式之职责链模式
职责链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。
下面模拟以下场景:你想向公司领导(经理<总监<总经理)提出请假或者加薪。不过你提出某些请求经理或者总监无权批准,得向总经理上报,让总经理定夺。
首先我们创建对象让它提供这个请求服务。因此我们得创建一个请求类。
class Request {
private String requestType; //申请类别
private String requestContent; //申请内容
private int number; //申请数量
public Request(String requestType, String requestContent, int number) {
this.requestType = requestType;
this.requestContent = requestContent;
this.number = number;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public void setRequestContent(String requestContent) {
this.requestContent = requestContent;
}
public void setNumber(int number) {
this.number = number;
}
public String getRequestType() {
return requestType;
}
public String getRequestContent() {
return requestContent;
}
public int getNumber() {
return number;
}
}
接下来创建对象来提供对请求做出处理的服务。因此我们创建一个管理者类。
class Manger {
private String name;
public Manger(String name) {
this.name = name;
}
public void getResult(String managerLevel, Request request){
//经理可以批2天以下的假,管不了加薪
if(managerLevel == "经理")
if(request.getRequestType() == "请假" && request.getNumber() <= 2)
System.out.println(name + ":" + request.getRequestContent()
+ request.getNumber() + "被批准" );
else
System.out.println(name + ":" + request.getRequestContent()
+ request.getNumber() + "我无权处理" );
//总监可以批5天以下的假,管不了加薪
else if(managerLevel == "总监")
if(request.getRequestType() == "请假" && request.getNumber() <= 5)
System.out.println(name + ":" + request.getRequestContent()
+ request.getNumber() + "被批准" );
else
System.out.println(name + ":" + request.getRequestContent()
+ request.getNumber() + "我无权处理" );
//总经理可以批任意天次的假,和五百以内的加薪。
else if(managerLevel == "总经理")
if(request.getRequestType() == "请假")
System.out.println(name + ":" + request.getRequestContent()
+ request.getNumber() + "被批准" );
else if(request.getRequestType() == "加薪" && request.getNumber() <= 500)
System.out.println(name + ":" + request.getRequestContent()
+ request.getNumber() + "被批准" );
else if (request.getRequestType() == "加薪" && request.getNumber() > 500)
System.out.println(name + ":" + request.getRequestContent()
+ request.getNumber() + "再说吧" );
}
}
最后创建一个客户端类,用于提交申请且回馈处理结果。
public class Client {
public static void main(String[] args) {
Manger jingli = new Manger("经理");
Manger zongjian = new Manger("总监");
Manger zongjingli = new Manger("总经理");
Request request1 = new Request("请假","小菜请假",2);
Request request3 = new Request("请假","小菜请假",5);
Request request2 = new Request("加薪", "小菜加薪", 500);
jingli.getResult("经理", request1);
zongjian.getResult("总监", request1);
zongjingli.getResult("总经理", request1);
System.out.println();
jingli.getResult("经理", request3);
zongjian.getResult("总监", request3);
zongjingli.getResult("总经理", request3);
System.out.println();
jingli.getResult("经理", request2);
zongjian.getResult("总监", request2);
zongjingli.getResult("总经理", request2);
}
}

看看以上代码会发现很多问题。
1.管理者类getResult()方法比较长,分支判断太多。
2.想在管理者类中添加其他管理者(比如项目经理,部门经理什么的)就意味着都需要去修改这个类,这个类承担了太多责任违背了单一职责原则,增加新的管理者需要修改这个类违背了和开放-封闭原则。
从逻辑上讲:我们想要请假是直接去找自己的上级————经理。当我们的上级处理不了了他就会去找他的上级。如此继续直到请假这个请求得到结果。但上述代码并没有体现出这个过程。
那么如何解决这个问题呢?我们看看职责链模式是如何做的。
/*
创建一个抽象的管理这类,这个类的对象提供两个服务:
1.处理自己能处理的请求。
2.将自己不能处理的请求传递给下一级管理者。
*/
abstract class Handler {
protected Handler handler;
//设置下一级管理者
public void setNextHandler(Handler nextHandler){
this.handler = nextHandler;
}
//处理请求的抽象方法
public abstract void HandleRequest(Request request);
}
/*
创建各级别的管理者,他们都得实现HandleRequest方法来处理请求。
*/
class JingLi extends Handler {
private String name;
public JingLi(String name) {
this.name = name;
}
@Override
public void HandleRequest(Request request) {
if(request.getNumber() >= 0 && request.getNumber() < 2)
System.out.println(name + ":" + request.getRequestType() + " " +
request.getRequestContent() + " " + request.getNumber() + " " + "批准");
else //若不能处理当前请求,将请求传递给下一级管理者
handler.HandleRequest(request);
}
}
class ZongJian extends Handler {
private String name;
public ZongJian(String name) {
this.name = name;
}
@Override
public void HandleRequest(Request request) {
if(request.getNumber() >= 2 && request.getNumber() < 5)
System.out.println(name + ":" + request.getRequestType() + " " +
request.getRequestContent() + " " + request.getNumber() + " " +"批准");
else
handler.HandleRequest(request);
}
}
class ZongJingLi extends Handler {
private String name;
public ZongJingLi(String name) {
this.name = name;
}
@Override
public void HandleRequest(Request request) {
if(request.getRequestType() == "请假")
if(request.getNumber() > 5)
System.out.println(name + ":" + request.getRequestType() + " " +
request.getRequestContent() + " " + request.getNumber() + " " +"批准");
if(request.getRequestType() == "加薪")
if(request.getNumber() <= 1000)
System.out.println(name + ":" + request.getRequestType() + " " +
request.getRequestContent() + " " + request.getNumber() + " " +"批准");
else if(request.getNumber() > 1000)
System.out.println(name + ":" + request.getRequestType() + " " +
request.getRequestContent() + " " + request.getNumber() + " " +"再说吧");
else
handler.HandleRequest(request);
}
}
/*
请求类,此类的对象提供请求信息的服务。
*/
class Request {
private String requestType; //申请类别
private String requestContent; //申请内容
private int number; //申请数量
public Request(String requestType, String requestContent, int number) {
this.requestType = requestType;
this.requestContent = requestContent;
this.number = number;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public void setRequestContent(String requestContent) {
this.requestContent = requestContent;
}
public void setNumber(int number) {
this.number = number;
}
public String getRequestType() {
return requestType;
}
public String getRequestContent() {
return requestContent;
}
public int getNumber() {
return number;
}
}
/*
客户端类:用于提交请求
*/
public class Client {
public static void main(String[] args) {
//创建各种请求
Request request1 = new Request("请假", "小菜请假", 1);
Request request2 = new Request("请假", "小菜请假", 10);
Request request3 = new Request("加薪", "小菜加薪", 1000);
Request request4 = new Request("加薪", "小菜加薪", 1500);
//创建管理者对象
Handler jingLi = new JingLi("经理");
Handler zongJian = new ZongJian("总监");
Handler zongjingli = new ZongJingLi("总经理");
/*
将管理者之间的关系链起来(经理<总监<总经理)
*/
jingLi.setNextHandler(zongJian);
zongJian.setNextHandler(zongjingli);
//提交请求。
/*jingLi.HandleRequest(request1);
jingLi.HandleRequest(request2);*/
jingLi.HandleRequest(request2);
}
}
将管理者类做成抽象的,方便我们增加不同的管理者类别(只需继承这个抽象的管理者类,实现HandleRequest()方法即可)。
将管理者关系链起来,当客户提出一个请求时,请求是沿链传递的,直到有一个管理者能处理它。这样做大大降低了耦合度。

浙公网安备 33010602011771号