通俗易懂设计模式(责任链模式)
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许将多个对象组成一个链式结构,并在这个链式结构中传递一个请求。每个对象都可以处理这个请求,或者将它传递给下一个对象。责任链模式的主要目的是在处理请求时实现解耦,让多个对象都有机会处理这个请求,而不是将这个请求的处理逻辑集中在一个对象中。
责任链模式的主要组成部分包括:
- 处理器(Handler):定义了一个接口,用于处理请求。处理器可以是一个抽象类或者一个接口。
- 具体处理器(ConcreteHandler):实现了处理器接口,并在其中定义了一个指向下一个处理器的引用。具体处理器可以处理请求,也可以将请求传递给下一个处理器。
责任链模式的优点:
- 解耦:责任链模式将请求的处理逻辑分散在多个处理器中,降低了各个处理器之间的耦合度。
- 灵活性:责任链模式允许在运行时动态地添加或删除处理器,从而实现了更高的灵活性。
- 可扩展性:责任链模式可以通过添加新的处理器来扩展系统的功能,而不需要修改已有的代码。
Java 实现责任链模式的示例代码:
// 处理器接口
public abstract class Handler {
protected Handler next;
public void setNext(Handler next) {
this.next = next;
}
public abstract void handleRequest(int request);
}
// 具体处理器 A
public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("ConcreteHandlerA: handle request " + request);
} else if (next != null) {
next.handleRequest(request);
}
}
}
// 具体处理器 B
public class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("ConcreteHandlerB: handle request " + request);
} else if (next != null) {
next.handleRequest(request);
}
}
}
// 具体处理器 C
public class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 20 && request < 30) {
System.out.println("ConcreteHandlerC: handle request " + request);
} else if (next != null) {
next.handleRequest(request);
}
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();
handlerA.setNext(handlerB);
handlerB.setNext(handlerC);
handlerA.handleRequest(5);
handlerA.handleRequest(15);
handlerA.handleRequest(25);
}
}
在这个示例中,我们定义了一个处理器接口 Handler
,它包含了一个 handleRequest()
方法。接着,我们定义了三个具体处理器类 ConcreteHandlerA
、ConcreteHandlerB
和 ConcreteHandlerC
,它们都实现了 Handler
接口,并在其中定义了一个指向下一个处理器的引用。在具体处理器类的 handleRequest()
方法中,我们根据请求的值来判断是否需要处理这个请求,或者将请求传递给下一个处理器。
在客户端代码中,我们创建了三个具体处理器对象,并通过 setNext()
方法将它们组成一个链式结构。然后,我们通过第一个处理器对象 handlerA
来处理一些请求。通过这个链式结构,我们可以在处理请求时实现解耦,让多个对象都有机会处理这个请求,而不是将这个请求的处理逻辑集中在一个对象中。这样,我们就将请求的处理过程封装在了具体处理器类中,使得请求的处理变得更加灵活和可扩展。
场景举例
场景一:请假审批流程
在一个公司中,员工请假需要经过多个部门的审批,例如直接上级、部门经理、人力资源部门等。为了实现这个审批流程,我们可以使用责任链模式。
使用责任链模式来实现请假审批流程,可以让代码更加简洁、易于维护。具体实现如下:
// 请假审批请求类
class LeaveRequest {
private String employeeName;
private int days;
public LeaveRequest(String employeeName, int days) {
this.employeeName = employeeName;
this.days = days;
}
public String getEmployeeName() {
return employeeName;
}
public int getDays() {
return days;
}
}
// 审批人接口
interface Approver {
void approve(LeaveRequest request);
Approver getNext();
void setNext(Approver next);
}
// 具体审批人实现,直接上级
class Supervisor extends Approver {
private Approver next;
@Override
public void approve(LeaveRequest request) {
if (request.getDays() <= 2) {
System.out.println(request.getEmployeeName() + "的请假申请已经被直接上级批准");
} else {
if (next != null) {
next.approve(request);
} else {
System.out.println(request.getEmployeeName() + "的请假申请没有后续审批人,无法处理");
}
}
}
@Override
public Approver getNext() {
return next;
}
@Override
public void setNext(Approver next) {
this.next = next;
}
}
// 具体审批人实现,部门经理
class DepartmentManager extends Approver {
private Approver next;
@Override
public void approve(LeaveRequest request) {
if (request.getDays() <= 5) {
System.out.println(request.getEmployeeName() + "的请假申请已经被部门经理批准");
} else {
if (next != null) {
next.approve(request);
} else {
System.out.println(request.getEmployeeName() + "的请假申请没有后续审批人,无法处理");
}
}
}
@Override
public Approver getNext() {
return next;
}
@Override
public void setNext(Approver next) {
this.next = next;
}
}
// 具体审批人实现,人力资源部门
class HRDepartment extends Approver {
private Approver next;
@Override
public void approve(LeaveRequest request) {
System.out.println(request.getEmployeeName() + "的请假申请已经被人力资源部门批准");
}
@Override
public Approver getNext() {
return next;
}
@Override
public void setNext(Approver next) {
this.next = next;
}
}
// 请假审批流程管理器
class LeaveApprovalManager {
private Approver supervisor;
private Approver departmentManager;
private Approver hrDepartment;
public LeaveApprovalManager(Approver supervisor, Approver departmentManager, Approver hrDepartment) {
this.supervisor = supervisor;
this.departmentManager = departmentManager;
this.hrDepartment = hrDepartment;
this.supervisor.setNext(this.departmentManager);
this.departmentManager.setNext(this.hrDepartment);
}
public void approve(LeaveRequest request) {
supervisor.approve(request);
}
}
// 测试类
public class ChainOfResponsibilityPatternDemo {
public static void main(String[] args) {
Approver supervisor = new Supervisor();
Approver departmentManager = new DepartmentManager();
Approver hrDepartment = new HRDepartment();
LeaveApprovalManager manager = new LeaveApprovalManager(supervisor, departmentManager, hrDepartment);
LeaveRequest request1 = new LeaveRequest("张三", 1);
LeaveRequest request2 = new LeaveRequest("李四", 4);
LeaveRequest request3 = new LeaveRequest("王五", 6);
manager.approve(request1);
manager.approve(request2);
manager.approve(request3);
}
}
场景二:在线购物订单处理流程
在一个在线购物网站中,用户下单后需要经过多个环节的处理,例如库存检查、支付处理、订单发货等。为了实现这个处理流程,我们可以使用责任链模式。
使用责任链模式来实现在线购物订单处理流程,可以让代码更加简洁、易于维护。具体实现如下:
// 订单类
class Order {
private String orderId;
private double amount;
public Order(String orderId, double amount) {
this.orderId = orderId;
this.amount = amount;
}
public String getOrderId() {
return orderId;
}
public double getAmount() {
return amount;
}
}
// 订单处理接口
interface OrderHandler {
void handle(Order order);
OrderHandler getNext();
void setNext(OrderHandler next);
}
// 具体订单处理实现,库存检查
class InventoryHandler extends OrderHandler {
private OrderHandler next;
@Override
public void handle(Order order) {
if (hasEnoughInventory(order)) {
System.out.println("订单 " + order.getOrderId() + " 的库存充足");
if (next != null) {
next.handle(order);
}
} else {
System.out.println("订单 " + order.getOrderId() + " 的库存不足");
}
}
private boolean hasEnoughInventory(Order order) {
// 这里可以添加实际的库存检查逻辑
return true;
}
@Override
public OrderHandler getNext() {
return next;
}
@Override
public void setNext(OrderHandler next) {
this.next = next;
}
}
// 具体订单处理实现,支付处理
class PaymentHandler extends OrderHandler {
private OrderHandler next;
@Override
public void handle(Order order) {
if (isPaymentConfirmed(order)) {
System.out.println("订单 " + order.getOrderId() + " 的支付已确认");
if (next != null) {
next.handle(order);
}
} else {
System.out.println("订单 " + order.getOrderId() + " 的支付未确认");
}
}
private boolean isPaymentConfirmed(Order order) {
// 这里可以添加实际的支付检查逻辑
return true;
}
@Override
public OrderHandler getNext() {
return next;
}
@Override
public void setNext(OrderHandler next) {
this.next = next;
}
}
// 具体订单处理实现,订单发货
class ShipmentHandler extends OrderHandler {
private OrderHandler next;
@Override
public void handle(Order order) {
System.out.println("订单 " + order.getOrderId() + " 已经发货");
}
@Override
public OrderHandler getNext() {
return next;
}
@Override
public void setNext(OrderHandler next) {
this.next = next;
}
}
// 订单处理流程管理器
class OrderProcessingManager {
private OrderHandler inventoryHandler;
private OrderHandler paymentHandler;
private OrderHandler shipmentHandler;
public OrderProcessingManager(OrderHandler inventoryHandler, OrderHandler paymentHandler, OrderHandler shipmentHandler) {
this.inventoryHandler = inventoryHandler;
this.paymentHandler = paymentHandler;
this.shipmentHandler = shipmentHandler;
this.inventoryHandler.setNext(this.paymentHandler);
this.paymentHandler.setNext(this.shipmentHandler);
}
public void process(Order order) {
inventoryHandler.handle(order);
}
}
// 测试类
public class ChainOfResponsibilityPatternDemo {
public static void main(String[] args) {
OrderHandler inventoryHandler = new InventoryHandler();
OrderHandler paymentHandler = new PaymentHandler();
OrderHandler shipmentHandler = new ShipmentHandler();
OrderProcessingManager manager = new OrderProcessingManager(inventoryHandler, paymentHandler, shipmentHandler);
Order order1 = new Order("001", 1000);
Order order2 = new Order("002", 2000);
Order order3 = new Order("003", 3000);
manager.process(order1);
manager.process(order2);
manager.process(order3);
}
}
在这两个场景中,我们都使用了责任链模式来实现复杂的处理流程。在第一个场景中,我们使用责任链模式来实现请假审批流程;在第二个场景中,我们使用责任链模式来实现在线购物订单处理流程。通过使用责任链模式,我们可以让代码更加简洁、易于维护,同时提高了代码的可扩展性和可重用性。
转载自:https://juejin.cn/post/7342384485697404982