1 定义
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
从定义分析:
- 对于一个请求会有多个对象对其进行转发。
- 请求的发送者和最终处理请求的接受者之间互相并不知道,没有任何耦合关系。
- 最终能够处理一个请求的对象有且只有一个,如果没有则表示处理过程or职责链设置出现错误。
何时使用:在处理消息的时候以过滤很多道。
如何解决:拦截的类都实现统一接口。
关键代码:Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。
优点:
- 1、降低耦合度。它将请求的发送者和接收者解耦。
- 2、简化了对象。使得对象不需要知道链的结构。
- 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
- 4、增加新的请求处理类很方便。
缺点:
- 1、不能保证请求一定被接收。
- 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
- 3、可能不容易观察运行时的特征,有碍于除错。
使用场景:
- 1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
- 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 3、可动态指定一组对象处理请求。
2 优势
- 客户提交一个请求时,请求沿链传递直至有一个ConcreteHandler对象负责处理它。
- 每一个ConcreteHandler仅需保持一个指向其后继者的引用,而不需保持它所有的候选者的引用。
- 由客户端来定义链的结构,因此可以随时增加or修改处理一个请求的结构。增强了给对象指派职责的灵活性。
3 UML
4 例子
4.1 场景
公司最底层员工通过提交申请,发起请假、加薪申请。经过逐层次审批,得到申请结果。
4.2 UML
4.3 code
Main
public class Main {
public 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.setType("请假");
request.setContent("小菜请假");
request.setNumber(2);
jinli.handleRequest(request);
Request request1=new Request();
request1.setType("请假");
request1.setContent("小菜请假");
request1.setNumber(4);
jinli.handleRequest(request1);
Request request2=new Request();
request2.setType("加薪");
request2.setContent("小菜加薪");
request2.setNumber(500);
jinli.handleRequest(request2);
Request request3=new Request();
request3.setType("加薪");
request3.setContent("小菜加薪");
request3.setNumber(1000);
jinli.handleRequest(request3);
}
}
Request
public class Request {
//申请类别
private String type;
//申请内容
private String content;
//申请数量
private int number;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
Manager
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 handleRequest(Request request);
}
CommonManager
//经理
public class CommonManager extends Manager {
public CommonManager(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
if(request.getType().equals("请假")&&request.getNumber()<=2){
System.out.println(name+":"+request.getContent()+request.getNumber()+"天的请求得到批准!");
}else{
if(superior!=null)
superior.handleRequest(request);
}
}
}
Majordomo
//总监
public class Majordomo extends Manager {
public Majordomo(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
if(request.getType().equals("请假")&&request.getNumber()<=5){
System.out.println(name+":"+request.getContent()+request.getNumber()+"天的请求得到批准!");
}else{
if(superior!=null)
superior.handleRequest(request);
}
}
}
GeneralManager
//总经理
public class GeneralManager extends Manager {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
if (request.getType().equals("请假")) {
System.out.println(name + ":" + request.getContent() + request.getNumber() + "天的请求得到批准!");
} else if (request.getType().equals("加薪") && request.getNumber() <= 500) {
System.out.println(name + ":" + request.getContent() + request.getNumber() + "元,请求得到批准!");
} else if (request.getType().equals("加薪") && request.getNumber() > 500) {
System.out.println(name + ":" + request.getContent() + request.getNumber() + "元,再说吧!");
}
}
}
运行结果
经理:小菜请假2天的请求得到批准!
总监:小菜请假4天的请求得到批准!
总经理:小菜加薪500元,请求得到批准!
总经理:小菜加薪1000元,再说吧!