通俗易懂设计模式(责任链模式)

133 阅读6分钟

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许将多个对象组成一个链式结构,并在这个链式结构中传递一个请求。每个对象都可以处理这个请求,或者将它传递给下一个对象。责任链模式的主要目的是在处理请求时实现解耦,让多个对象都有机会处理这个请求,而不是将这个请求的处理逻辑集中在一个对象中。

责任链模式的主要组成部分包括:

  1. 处理器(Handler):定义了一个接口,用于处理请求。处理器可以是一个抽象类或者一个接口。
  2. 具体处理器(ConcreteHandler):实现了处理器接口,并在其中定义了一个指向下一个处理器的引用。具体处理器可以处理请求,也可以将请求传递给下一个处理器。

责任链模式的优点:

  1. 解耦:责任链模式将请求的处理逻辑分散在多个处理器中,降低了各个处理器之间的耦合度。
  2. 灵活性:责任链模式允许在运行时动态地添加或删除处理器,从而实现了更高的灵活性。
  3. 可扩展性:责任链模式可以通过添加新的处理器来扩展系统的功能,而不需要修改已有的代码。

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() 方法。接着,我们定义了三个具体处理器类 ConcreteHandlerAConcreteHandlerBConcreteHandlerC,它们都实现了 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);
    }
}

在这两个场景中,我们都使用了责任链模式来实现复杂的处理流程。在第一个场景中,我们使用责任链模式来实现请假审批流程;在第二个场景中,我们使用责任链模式来实现在线购物订单处理流程。通过使用责任链模式,我们可以让代码更加简洁、易于维护,同时提高了代码的可扩展性和可重用性。