责任链模式让多个对象依次处理请求,降低发送者和接收者的耦合度,以在线购物为例,用户提交订单需经多步验证,通过责任链模式,验证器按顺序处理请求,先用户身份,再支付方式,最后配送地址,任一验证失败即停止流程并反馈错误,责任链模式提升了代码的灵活性和可扩展性。
责任链模式是一种行为设计模式,它使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,这些对象形成一个处理请求的链,client只需要将请求发送到链头即可。举一个业务中的例子:假设有一个在线购物网站,用户可以在网站上浏览商品并购买,在用户提交订单时,需要验证用户的身份、支付方式、配送地址等信息,可以使用责任链模式来处理这个流程,假设有以下验证器:
可以将这些验证器组成一个责任链,并让它们依次处理请求,当用户提交订单时,责任链模式的第一个验证器(用户身份验证器)会首先处理请求,如果身份信息验证通过,它会将请求传递给下一个验证器(支付方式验证器),如果支付方式验证通过,再传递给下一个验证器(配送地址验证器),如果任何一个验证器不通过,整个流程就会停止,并返回相应的错误信息给用户。这样,就可以避免将请求发送者和接收者之间的耦合关系,使得代码更加灵活和可扩展。
在未使用责任链模式的情况下,可能会将多个处理逻辑放在一个方法中,或者在一个方法中依次调用多个处理方法,这种方式会导致代码的可维护性和可扩展性降低,因为当需要添加或修改处理逻辑时,必须修改这个方法,下面是一个未使用责任链模式的反例代码:
// 订单验证类,未使用责任链模式
public class OrderValidator {
// 验证用户身份
private boolean validateUser(User user) {
// 模拟验证逻辑
return user != null && user.isAuthenticated();
}
// 验证支付方式
private boolean validatePayment(Payment payment) {
// 模拟验证逻辑
return payment != null && payment.isAvailable();
}
// 验证配送地址
private boolean validateAddress(Address address) {
// 模拟验证逻辑
return address != null && address.isValid();
}
// 提交订单方法,包含所有验证逻辑
public String submitOrder(User user, Payment payment, Address address) {
if (!validateUser(user)) {
return "用户身份验证失败!";
}
if (!validatePayment(payment)) {
return "支付方式验证失败!";
}
if (!validateAddress(address)) {
return "配送地址验证失败!";
}
// 所有验证通过,处理订单
return "订单提交成功!";
}
}
// 客户端调用案例
public class Client {
public static void main(String[] args) {
OrderValidator validator = new OrderValidator();
// 创建用户、支付方式和配送地址对象
User user = new User(); // 假设已经认证
Payment payment = new Payment(); // 假设可用
Address address = new Address(); // 假设有效
// 提交订单并打印结果
String result = validator.submitOrder(user, payment, address);
System.out.println(result); // 输出:订单提交成功!
// 尝试使用无效的用户提交订单
User invalidUser = null; // 无效用户
String invalidUserResult = validator.submitOrder(invalidUser, payment, address);
System.out.println(invalidUserResult); // 输出:用户身份验证失败!
}
}
// 假设存在的其他类
class User {
public boolean isAuthenticated() {
// 模拟认证逻辑
return true;
}
}
class Payment {
public boolean isAvailable() {
// 模拟支付方式可用逻辑
return true;
}
}
class Address {
public boolean isValid() {
// 模拟地址验证逻辑
return true;
}
}
在上面的代码中,OrderValidator
类负责处理订单提交前的所有验证逻辑,submitOrder
方法中依次调用了用户验证、支付方式验证和配送地址验证方法,如果任何一个验证失败,方法都会立即返回错误信息,只有当所有验证都通过时,才会返回成功信息。
client代码创建了一个订单验证器实例,并尝试使用不同的用户提交订单,第一次提交使用有效用户,因此成功,第二次提交使用无效用户(null
),因此失败,并返回相应的错误信息。
这种方式的问题是,如果需要添加新的验证逻辑(比如库存验证),必须修改 submitOrder
方法,这违反了开闭原则(对扩展开放,对修改关闭),此外,如果验证逻辑变得复杂,submitOrder
方法会变得非常庞大和难以维护。
当使用责任链模式时,可以创建一个处理请求的链,每个链上的节点都有机会处理该请求,如果某个节点能够处理请求,则处理它并可能结束链的进一步处理,否则,它将请求传递给链上的下一个节点,以下是一个使用了责任链模式的正例代码实现:
// 抽象处理者角色
abstract class Handler {
protected Handler successor; // 下一个处理者
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(Request request); // 处理请求的抽象方法
}
// 具体处理者角色A - 用户验证
class UserHandler extends Handler {
@Override
public void handleRequest(Request request) {
if (request instanceof UserRequest) {
UserRequest userRequest = (UserRequest) request;
if (userRequest.getUser() != null && userRequest.getUser().isAuthenticated()) {
System.out.println("用户验证通过!");
} else {
System.out.println("用户验证失败!");
return; // 验证失败,不再传递请求
}
}
// 如果本处理者处理后请求未被结束,则继续传递
if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者角色B - 支付验证
class PaymentHandler extends Handler {
@Override
public void handleRequest(Request request) {
if (request instanceof PaymentRequest) {
PaymentRequest paymentRequest = (PaymentRequest) request;
if (paymentRequest.getPayment() != null && paymentRequest.getPayment().isAvailable()) {
System.out.println("支付验证通过!");
} else {
System.out.println("支付验证失败!");
return; // 验证失败,不再传递请求
}
}
// 如果本处理者处理后请求未被结束,则继续传递
if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者角色C - 地址验证
class AddressHandler extends Handler {
@Override
public void handleRequest(Request request) {
if (request instanceof AddressRequest) {
AddressRequest addressRequest = (AddressRequest) request;
if (addressRequest.getAddress() != null && addressRequest.getAddress().isValid()) {
System.out.println("地址验证通过!");
} else {
System.out.println("地址验证失败!");
return; // 验证失败,不再传递请求
}
}
// 正常情况下,这里可以处理请求或结束处理,但为了示例简单性,不在这里做任何额外处理
}
}
// 请求接口
interface Request {
}
// 用户请求
class UserRequest implements Request {
private User user;
public UserRequest(User user) {
this.user = user;
}
public User getUser() {
return user;
}
}
// 支付请求
class PaymentRequest implements Request {
private Payment payment;
public PaymentRequest(Payment payment) {
this.payment = payment;
}
public Payment getPayment() {
return payment;
}
}
// 地址请求
class AddressRequest implements Request {
private Address address;
public AddressRequest(Address address) {
this.address = address;
}
public Address getAddress() {
return address;
}
}
// 用户类
class User {
private boolean authenticated;
public User(boolean authenticated) {
this.authenticated = authenticated;
}
public boolean isAuthenticated() {
return authenticated;
}
}
// 支付类
class Payment {
private boolean available;
public Payment(boolean available) {
this.available = available;
}
public boolean isAvailable() {
return available;
}
}
// 地址类
class Address {
private boolean valid;
public Address(boolean valid) {
this.valid = valid;
}
public boolean isValid() {
return valid;
}
}
// 客户端调用案例
public class Client {
public static void main(String[] args) {
// 创建责任链
Handler userHandler = new UserHandler();
Handler paymentHandler = new PaymentHandler();
Handler addressHandler = new AddressHandler();
userHandler.setSuccessor(paymentHandler);
paymentHandler.setSuccessor(addressHandler);
// 创建请求并发送给责任链
User user = new User(true);
Payment payment = new Payment(true);
Address address = new Address(true);
// 发送用户请求
userHandler.handleRequest(new UserRequest(user));
// 发送支付请求
userHandler.handleRequest(new PaymentRequest(payment));
// 发送地址请求
userHandler.handleRequest(new AddressRequest(address));
// 尝试使用无效用户发送请求
User invalidUser = new User(false);
userHandler.handleRequest(new UserRequest(invalidUser));
}
}
在上述代码中,创建了三个具体处理者(UserHandler
, PaymentHandler
, AddressHandler
),它们分别处理用户验证、支付验证和地址验证,每个处理者都实现了抽象处理者Handler
定义的接口,并且可以在处理请求时将请求传递给链中的下一个处理者。
在client中创建了一个责任链,每个请求都被传递给链中的适当处理者,如果处理者能够处理该请求,则处理它,否则将其传递给下一个处理者,当客户端尝试使用无效用户发送请求时,用户验证处理者会捕获这个条件并输出错误消息,同时停止请求的进一步处理。
责任链模式是一种行为设计模式,它允许对象对请求进行处理,或者将其传递给链中的下一个处理者,这种模式可以消除请求的发送者和接收者之间的耦合,它如下特点:
优点:
缺点:
使用建议:
完!