一.职责链模式介绍与使用场景
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求沿着处理链进行传递,直到有一个处理者能够处理该请求。每个处理者都可以决定是否将请求传递给下一个处理者,从而形成一条处理链。
职责链模式通常由以下几个角色组成:
- 抽象处理者(Abstract Handler):定义一个处理请求的接口,并持有下一个处理者的引用。
- 具体处理者(Concrete Handler):实现抽象处理者接口,处理它所负责的请求,如果自己无法处理,则将请求传递给下一个处理者。
职责链模式的使用场景
当有多个对象可以处理同一请求,并且具体哪个对象处理请求在运行时决定时,职责链模式非常有用。该模式允许请求按照顺序通过处理链进行传递,直到找到能够处理请求的对象。
当需要动态添加或移除处理对象,并且不希望手动编写大量条件判断语句来决定由哪个对象处理请求时,职责链模式提供了一种灵活的解决方案。新的处理对象可以通过继承抽象处理者类并插入到处理链中,从而实现动态的处理对象管理。
当需要在不同的处理对象间进行解耦,以便每个对象都可以独立进行处理并修改其处理方式时,职责链模式非常适用。每个处理对象只需要关注自己负责的部分,而不需要了解整个处理过程。
当希望在处理请求时,可以灵活地决定请求的处理顺序或者只有部分处理者处理请求时,职责链模式提供了一种机制。通过调整处理链中处理者的顺序或者配置不同的处理链,可以灵活地控制请求的处理流程。
总结起来,职责链模式适用于以下情况:
- 存在多个对象可以处理同一请求,且运行时决定哪个对象处理请求。
- 需要动态添加或移除处理对象,避免大量的条件判断语句。
- 需要解耦处理对象,使每个对象可以独立处理请求。
- 希望灵活地控制请求的处理顺序或只有部分处理者处理请求。
职责链模式提供了一种灵活、可扩展且松耦合的方式来处理请求,适用于需要处理对象之间解耦和动态调整处理流程的场景。
二.职责链模式实现
我们先用一个简单的例子来实现职责链模式:
// 抽象处理者
abstract class Handler {
private Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public void handleRequest(Request request) {
if (canHandle(request)) {
processRequest(request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("No handler found for the request.");
}
}
protected abstract boolean canHandle(Request request);
protected abstract void processRequest(Request request);
}
// 具体处理者 - 文件处理器
class FileHandler extends Handler {
protected boolean canHandle(Request request) {
return request.getType().equals("file");
}
protected void processRequest(Request request) {
System.out.println("FileHandler is processing the request: " + request.getData());
}
}
// 具体处理者 - 数据库处理器
class DatabaseHandler extends Handler {
protected boolean canHandle(Request request) {
return request.getType().equals("database");
}
protected void processRequest(Request request) {
System.out.println("DatabaseHandler is processing the request: " + request.getData());
}
}
// 具体处理者 - API处理器
class ApiHandler extends Handler {
protected boolean canHandle(Request request) {
return request.getType().equals("api");
}
protected void processRequest(Request request) {
System.out.println("ApiHandler is processing the request: " + request.getData());
}
}
// 请求类
class Request {
private String type;
private String data;
public Request(String type, String data) {
this.type = type;
this.data = data;
}
public String getType() {
return type;
}
public String getData() {
return data;
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
Handler fileHandler = new FileHandler();
Handler databaseHandler = new DatabaseHandler();
Handler apiHandler = new ApiHandler();
fileHandler.setNextHandler(databaseHandler);
databaseHandler.setNextHandler(apiHandler);
Request fileRequest = new Request("file", "SampleFile.txt");
Request databaseRequest = new Request("database", "SELECT * FROM Users");
Request apiRequest = new Request("api", "POST /api/users");
fileHandler.handleRequest(fileRequest);
fileHandler.handleRequest(databaseRequest);
fileHandler.handleRequest(apiRequest);
}
}
我们定义了抽象处理者 Handler
,其中包含了处理请求的方法 handleRequest
。具体处理者类 FileHandler
、DatabaseHandler
和 ApiHandler
分别继承了抽象处理者类,并实现了抽象方法 canHandle
和 processRequest
。
在 Main
类的 main
方法中,我们创建了一个处理链,并将请求依次传递给处理链中的处理者。如果某个处理者可以处理该请求,则处理请求;否则,将请求传递给下一个处理者。通过这种方式,请求会沿着处理链进行传递,直到找到可以处理它的处理者。
在示例中,我们创建了三种类型的请求:文件请求、数据库请求和API请求,并将它们依次传递给处理链的第一个处理者。根据请求的类型,每个处理者判断是否可以处理该请求,如果可以,则进行相应的处理;否则,将请求传递给下一个处理者。
职责链模式在实际项目中被应用最多的应该是OA的处理流程了,下面我们用职责链模式来实现一个OA流程:
// 请求类
class PurchaseRequest {
private String product;
private double price;
public PurchaseRequest(String product, double price) {
this.product = product;
this.price = price;
}
public String getProduct() {
return product;
}
public double getPrice() {
return price;
}
}
// 抽象处理者
abstract class Approver {
protected Approver successor;
public void setSuccessor(Approver successor) {
this.successor = successor;
}
public abstract void processRequest(PurchaseRequest request);
}
// 具体处理者 - 销售经理
class SalesManager extends Approver {
public void processRequest(PurchaseRequest request) {
if (request.getPrice() <= 1000) {
System.out.println("Sales Manager approves the purchase of " + request.getProduct());
} else if (successor != null) {
successor.processRequest(request);
}
}
}
// 具体处理者 - 财务经理
class FinanceManager extends Approver {
public void processRequest(PurchaseRequest request) {
if (request.getPrice() <= 5000) {
System.out.println("Finance Manager approves the purchase of " + request.getProduct());
} else if (successor != null) {
successor.processRequest(request);
}
}
}
// 具体处理者 - CEO
class CEO extends Approver {
public void processRequest(PurchaseRequest request) {
if (request.getPrice() <= 10000) {
System.out.println("CEO approves the purchase of " + request.getProduct());
} else {
System.out.println("Purchase request for " + request.getProduct() + " denied by CEO");
}
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
Approver salesManager = new SalesManager();
Approver financeManager = new FinanceManager();
Approver ceo = new CEO();
salesManager.setSuccessor(financeManager);
financeManager.setSuccessor(ceo);
PurchaseRequest request1 = new PurchaseRequest("Laptop", 800);
PurchaseRequest request2 = new PurchaseRequest("Smartphone", 3000);
PurchaseRequest request3 = new PurchaseRequest("Conference Table", 12000);
salesManager.processRequest(request1);
salesManager.processRequest(request2);
salesManager.processRequest(request3);
}
}
我们模拟了一个电商系统中的采购请求审批过程。我们有三个具体处理者:销售经理(Sales Manager)、财务经理(Finance Manager)和CEO。每个处理者都可以处理特定价格范围内的采购请求,如果自己无法处理,则将请求传递给下一个处理者。
在 Main
类的 main
方法中,我们创建了三个采购请求,并将它们依次传递给销售经理。销售经理首先尝试处理请求,如果请求的价格超出其处理能力,则将请求传递给财务经理。财务经理再次尝试处理请求,如果仍无法处理,则将请求传递给CEO。CEO是最后一个处理者,如果请求超出其处理能力,则请求被拒绝。
通过使用职责链模式,采购请求会依次通过处理链进行传递,直到找到能够处理它的处理者。这种方式使得处理请求的责任可以动态调整和扩展,而不需要显式的条件判断语句。