Java - GoF设计模式详解15(责任链模式)
作者:hangge | 2023-06-09 09:20
十五、责任链模式
1,基本介绍
(1)责任链模式(Chain of Responsibility):把可以响应请求的对象链接起来,并在链中传递请求,直到有一个对象处理这个请求。从而保证多个对象都有机会处理请求,减少请求的发送者与接收者之间的耦合。
(2)该模式中包含的角色及其职责如下:
- 抽象处理者(Handler)角色:定义了处理请求的接口,并且可以设置后继处理者。
- 具体处理者(Concrete Handler)角色:实现了处理请求的方法,并且可以设置后继处理者。如果无法处理请求,则将请求转发给后继处理者。

2,使用样例
(1)下面我通过用户订单请求的处理(订货量小于 1000 的由经理处理,小于 10000 的由主任处理,大于等于 10000 的由董事长处理)来演示责任链模式的使用。首先我们定义一个订单请求类 OrderRequest:
// 订单请求类
public class OrderRequest {
private String customer; //客户姓名
private int amount; //订货量
public OrderRequest(String customer, int amount) {
this.customer = customer;
this.amount = amount;
}
public String getCustomer() {
return customer;
}
public int getAmount() {
return amount;
}
}
(2)接着定义一个抽象的处理者类 OrderHandler:
// 抽象处理者类
public abstract class OrderHandler {
// 下一个处理者
protected OrderHandler successor;
// 设置下一个处理者
public void setSuccessor(OrderHandler successor) {
this.successor = successor;
}
// 处理订单请求的方法
public abstract void handleOrder(OrderRequest request);
}
(3)然后就是定义3个具体的处理者类,分别是 ManagerOrderHandler、DirectorOrderHandler 和 CEOOrderHandler:
// 经理级别订单处理
public class ManagerOrderHandler extends OrderHandler {
@Override
public void handleOrder(OrderRequest request) {
if (request.getAmount() < 1000) {
System.out.println("经理处理来自" + request.getCustomer() + "的订单,订货量为"
+ request.getAmount());
} else {
successor.handleOrder(request);
}
}
}
// 主任级别订单处理
public class DirectorOrderHandler extends OrderHandler {
@Override
public void handleOrder(OrderRequest request) {
if (request.getAmount() < 10000) {
System.out.println("主任处理来自" + request.getCustomer() + "的订单,订货量为"
+ request.getAmount());
} else {
successor.handleOrder(request);
}
}
}
// 董事长级别订单处理
public class CEOOrderHandler extends OrderHandler {
@Override
public void handleOrder(OrderRequest request) {
System.out.println("董事长处理来自" + request.getCustomer() + "的订单,订货量为"
+ request.getAmount());
}
}
(4)最后我们使用责任链模式来处理用户的订单请求,我们先设置了三个处理者对象 manager、director 和 ceo,并且设置了它们的后继处理者。然后,我们发送了 4 个订单请求,每个请求都会在责任链上流动,直到有一个处理者能够处理该请求为止。
public class Test {
public static void main(String[] args) {
// 创建处理者对象
OrderHandler manager = new ManagerOrderHandler();
OrderHandler director = new DirectorOrderHandler();
OrderHandler ceo = new CEOOrderHandler();
// 设置后继处理者
manager.setSuccessor(director);
director.setSuccessor(ceo);
// 发送请求
manager.handleOrder(new OrderRequest("乔布斯", 12000));
manager.handleOrder(new OrderRequest("李老板", 500));
manager.handleOrder(new OrderRequest("hangge", 1500));
manager.handleOrder(new OrderRequest("刘总", 50000));
}
}
附一:JDK 中的责任链模式
(1)java.util.logging 包中的日志系统使用了责任链模式。当 Logger 对象收到一条日志消息时,它会将消息发送到它的后继节点。Logger 对象的后继节点可以是其他 Logger 对象,也可以是控制台、文件或其他输出目的地。这样,Logger 对象就可以将日志消息发送到多个输出目的地,从而实现了责任链模式的效果。
public class Test {
private static final Logger logger = Logger.getLogger(Test.class.getName());
public static void main(String[] args) {
logger.info("This is an info message.");
logger.warning("This is a warning message.");
logger.severe("This is a severe message.");
}
}
(2)在上面的示例代码中,我们并没有显式地创建 Logger 对象的后继节点。这是因为,在默认情况下,Logger 对象的后继节点是由 Java 虚拟机的日志记录配置文件决定的。如果要修改 Logger 对象的后继节点,可以使用 Logger 对象的 addHandler() 方法来添加新的后继节点。例如,可以使用以下代码来将一个文件输出流添加为 Logger 对象的后继节点:
- 下面的代码中,我们使用了 FileHandler 类来创建一个文件输出流,然后使用 Logger 对象的 addHandler() 方法将该输出流添加为 Logger 对象的后继节点。这样,Logger 对象就可以将日志消息发送到两个输出目的地:控制台和文件。
public class Test {
private static final Logger logger = Logger.getLogger(Test.class.getName());
public static void main(String[] args) throws Exception {
FileHandler fileHandler = new FileHandler("example.log");
logger.addHandler(fileHandler);
logger.info("This is an info message.");
logger.warning("This is a warning message.");
logger.severe("This is a severe message.");
}
}
附二:Spring 中的责任链模式
1,Spring MVC 中的拦截器(Interceptor)
拦截器是 Spring MVC 的一种常用机制,用于拦截请求并执行特定的操作。拦截器通常是按照定义的顺序依次执行,形成一个责任链。
2,Spring AOP 中的切面(Aspect)
Spring AOP 支持在特定方法调用前或之后执行某些操作,这些操作被称为切面。多个切面可以通过配置的优先级或执行顺序来构建责任链。
3,Spring 的事件传递机制(ApplicationEvent)
Spring 支持在应用中传递事件,这些事件可以被多个监听器(Listener)接收并处理。这些监听器可以按照定义的优先级或执行顺序依次执行,形成一个责任链。
附三:JavaScript 中的责任链模式
在 JavaScript 中,可以使用事件冒泡(event bubbling)机制来实现事件的传递。在事件冒泡中,事件从目标元素开始向上传递,每经过一个父元素就被触发一次。这种机制可以让多个元素对同一个事件进行响应,形成一个责任链。
全部评论(0)