浅谈Java设计模式——职责链模式(Chain Of Responsibility)
一、概述
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链, 并沿着这条链传递该请求,直到有一个对象处理它为止。 这一模式的想法是,给多个对象处理一个请求的机会,从而解耦发送者和接受者。
职责链模式描述的请求如何沿着对象所组成的链来传递的。它将对象组成一条链,发送者将请求发给链的第一个接收者,并且沿着这条链传递,直到有一个对象来处理它或者直到最后也没有对象处理而留在链末尾端。
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止,这就是职责链模式。在职责链模式中,使得每一个对象都有可能来处理请求,从而实现了请求的发送者和接收者之间的解耦。同时职责链模式简化了对象的结构,它使得每个对象都只需要引用它的后继者即可,而不必了解整条链,这样既提高了系统的灵活性也使得增加新的请求处理类也比较方便。但是在职责链中我们不能保证所有的请求都能够被处理,而且不利于观察运行时特征。
二、使用场景
1.有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
2.你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3.可处理一个请求的对象集合应被动态指定。
三、参与者
1.Handler 定义一个处理请求的接口。 (可选)实现后继链。
2.ConcreteHandler 处理它所负责的请求。 可访问它的后继者。 如果可处理该请求,就处理之;否则将该请求转发给它的后继者。
3.Client 向链上的具体处理者(ConcreteHandler)对象提交请求。
四、类图
五、示例代码
1.Bean
/**
* Bean
*
* @author zhipeng_Tong
*/
public class Requset {
private String requestType; // 申请类型
private String requsetContent; // 申请内容
private int number; // 数量
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public String getRequsetContent() {
return requsetContent;
}
public void setRequsetContent(String requsetContent) {
this.requsetContent = requsetContent;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
2.Handler
/**
* Handler
*
* @author zhipeng_Tong
*/
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;
}
// 申请请求
public abstract void requestApplications(Requset requset);
}
3.ConcreteHandler
/**
* ConcreteHandler
*
* @author zhipeng_Tong
*/
public class CommonManager extends Manager { // 经理
public CommonManager(String name) {
super(name);
}
@Override
public void requestApplications(Requset requset) {
if (requset.getRequestType().equals("请假") && requset.getNumber() <= 2) {
System.out.println(String.format("%s:%s 数量%s 被批准",
name, requset.getRequsetContent(), requset.getNumber()));
} else {
if (superior != null)
superior.requestApplications(requset);
}
}
}
/**
* ConcreteHandler
*
* @author zhipeng_Tong
*/
public class Majordomo extends Manager { // 总监
public Majordomo(String name) {
super(name);
}
@Override
public void requestApplications(Requset requset) {
if (requset.getRequestType().equals("请假") && requset.getNumber() <= 5) {
System.out.println(String.format("%s:%s 数量%s 被批准",
name, requset.getRequsetContent(), requset.getNumber()));
} else {
if (superior != null)
superior.requestApplications(requset);
}
}
}
/**
* ConcreteHandler
*
* @author zhipeng_Tong
*/
public class GeneralManager extends Manager { // 总经理
public GeneralManager(String name) {
super(name);
}
@Override
public void requestApplications(Requset requset) {
if (requset.getRequestType().equals("请假")) {
System.out.println(String.format("%s:%s 数量%s 被批准",
name, requset.getRequsetContent(), requset.getNumber()));
} else if (requset.getRequestType().equals("加薪") && requset.getNumber() <= 500) {
System.out.println(String.format("%s:%s 数量%s 被批准",
name, requset.getRequsetContent(), requset.getNumber()));
} else if (requset.getRequestType().equals("加薪") && requset.getNumber() > 500) {
System.out.println(String.format("%s:%s 数量%s 再说吧!",
name, requset.getRequsetContent(), requset.getNumber()));
} else {
System.out.println("你走吧!!!");
}
}
}
4.Client 向链上的具体处理者(ConcreteHandler)对象提交请求。
public class Client {
public static void main(String[] args) {
CommonManager commonManager = new CommonManager("经理");
Majordomo majordomo = new Majordomo("总监");
GeneralManager generalManager = new GeneralManager("总经理");
commonManager.setSuperior(majordomo);
majordomo.setSuperior(generalManager);
Requset requset = new Requset();
requset.setRequestType("请假");
requset.setRequsetContent("小明请假");
requset.setNumber(1);
commonManager.requestApplications(requset);
System.out.println("--------------------");
requset.setRequestType("请假");
requset.setRequsetContent("小明请假");
requset.setNumber(4);
commonManager.requestApplications(requset);
System.out.println("--------------------");
requset.setRequestType("加薪");
requset.setRequsetContent("小明请求加薪");
requset.setNumber(500);
commonManager.requestApplications(requset);
System.out.println("--------------------");
requset.setRequestType("加薪");
requset.setRequsetContent("小明请求加薪");
requset.setNumber(5000);
commonManager.requestApplications(requset);
System.out.println("--------------------");
}
}
运行结果
经理:小明请假 数量1 被批准
--------------------
总监:小明请假 数量4 被批准
--------------------
总经理:小明请求加薪 数量500 被批准
--------------------
总经理:小明请求加薪 数量5000 再说吧!
--------------------