记得三年前面试某金融科技公司时,技术总监曾抛出一个经典问题:“订单创建需要经过参数校验、库存检查、价格计算等多个环节,如何设计一个可扩展的流程处理架构?” 这个问题直击设计模式在复杂业务中的应用核心,也让我意识到:真正的代码质量保障,始于对设计模式的深度理解与灵活运用。
一、代码质量保障的基石:设计模式的战略价值
1. 设计模式与代码质量的三维关系
维度 | 设计模式的贡献 | 质量指标提升 |
---|---|---|
可维护性 | 降低耦合度(如工厂模式解耦对象创建) | 变更成本下降 40%(基于某电商系统数据) |
可扩展性 | 支持开闭原则(如观察者模式动态注册监听器) | 新功能开发周期缩短 30% |
可测试性 | 依赖注入(如工厂模式返回接口) | 单测覆盖率提升 25% |
2. 设计模式的选择矩阵
// 设计模式选择决策树(简化版)
public DesignPattern selectPattern(CodeSmell smell) {
if (smell.isLongConditional()) {
return new StrategyPattern();
} else if (smell.isTightCoupling()) {
return new FactoryPattern();
} else if (smell.isStateTransition()) {
return new StatePattern();
}
// 默认返回简单重构
return new ExtractMethod();
}
二、责任链模式:构建灵活的处理流程
1. 原理与结构
(1)核心定义
将请求的发送者和接收者解耦,使多个对象都有机会处理这个请求。请求沿着链传递,直到有一个对象处理它为止。
(2)结构组成
- Handler:定义处理请求的接口
- ConcreteHandler:实现处理逻辑,决定是否将请求传递给下一个处理器
- Client:创建处理链并发送请求
2. 实战场景:订单处理流程(电商系统)
(1)场景分析
订单创建需经过:参数校验→库存检查→价格计算→优惠应用→日志记录等环节,每个环节都可能终止流程。
(2)核心代码实现
// 订单处理器接口
public interface OrderHandler {
boolean process(OrderContext context);
void setNextHandler(OrderHandler nextHandler);
}
// 参数校验处理器
public class ParamValidationHandler implements OrderHandler {
private OrderHandler nextHandler;
@Override
public boolean process(OrderContext context) {
// 校验参数逻辑
if (context.getUserId() == null || context.getProductId() == null) {
context.setError("参数缺失");
return false;
}
// 传递给下一个处理器
return nextHandler != null ? nextHandler.process(context) : true;
}
@Override
public void setNextHandler(OrderHandler nextHandler) {
this.nextHandler = nextHandler;
}
}
// 库存检查处理器
public class InventoryCheckHandler implements OrderHandler {
private final InventoryService inventoryService;
public InventoryCheckHandler(InventoryService inventoryService) {
this.inventoryService = inventoryService;
}
@Override
public boolean process(OrderContext context) {
// 检查库存逻辑
if (!inventoryService.hasStock(context.getProductId(), context.getQuantity())) {
context.setError("库存不足");
return false;
}
return nextHandler != null ? nextHandler.process(context) : true;
}
// 省略setNextHandler实现
}
// 客户端:构建处理链并执行
public class OrderService {
public OrderResult createOrder(OrderDTO orderDTO) {
// 构建处理链
OrderHandler paramValidator = new ParamValidationHandler();
OrderHandler inventoryChecker = new InventoryCheckHandler(inventoryService);
OrderHandler priceCalculator = new PriceCalculationHandler();
// 设置链顺序
paramValidator.setNextHandler(inventoryChecker);
inventoryChecker.setNextHandler(priceCalculator);
// 创建上下文并处理
OrderContext context = new OrderContext(orderDTO);
boolean success = paramValidator.process(context);
return success ?
OrderResult.success(context.getOrder()) :
OrderResult.fail(context.getError());
}
}
(3)工程优势
- 流程可视化:通过 Handler 实现类名称直接反映处理步骤
- 易于扩展:新增校验逻辑只需实现 Handler 并插入链中
- 单元测试友好:可单独测试每个 Handler 的逻辑正确性
三、工厂模式:解耦对象创建与使用
1. 原理与结构
(1)核心定义
定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
(2)结构组成
- Product:定义产品的接口
- ConcreteProduct:实现产品接口的具体类
- Creator:声明工厂方法,返回产品对象
- ConcreteCreator:实现工厂方法,创建具体产品
2. 实战场景:支付渠道选择(金融系统)
(1)场景分析
系统支持支付宝、微信、银行卡等多种支付方式,需根据用户选择动态创建支付处理器。
(2)核心代码实现
// 支付处理器接口
public interface PaymentProcessor {
PaymentResult process(PaymentRequest request);
}
// 支付宝处理器
public class AlipayProcessor implements PaymentProcessor {
private final AlipayClient alipayClient;
@Override
public PaymentResult process(PaymentRequest request) {
// 支付宝支付逻辑
AlipayTradeRequest alipayRequest = convertToAlipayRequest(request);
AlipayTradeResponse response = alipayClient.execute(alipayRequest);
return mapToPaymentResult(response);
}
}
// 微信支付处理器
public class WechatPayProcessor implements PaymentProcessor {
private final WechatPayClient wechatPayClient;
@Override
public PaymentResult process(PaymentRequest request) {
// 微信支付逻辑
WechatPayRequest wechatRequest = convertToWechatRequest(request);
WechatPayResponse response = wechatPayClient.execute(wechatRequest);
return mapToPaymentResult(response);
}
}
// 支付工厂
public class PaymentProcessorFactory {
// 工厂方法:根据支付类型创建处理器
public PaymentProcessor createProcessor(PaymentType type) {
switch (type) {
case ALIPAY:
return new AlipayProcessor(alipayClient);
case WECHAT_PAY:
return new WechatPayProcessor(wechatPayClient);
case BANK_CARD:
return new BankCardProcessor(bankCardClient);
default:
throw new IllegalArgumentException("不支持的支付类型: " + type);
}
}
}
// 客户端使用
public class PaymentService {
private final PaymentProcessorFactory factory;
public PaymentResult executePayment(PaymentDTO paymentDTO) {
// 通过工厂创建处理器
PaymentProcessor processor = factory.createProcessor(paymentDTO.getType());
// 执行支付
return processor.process(convertToRequest(paymentDTO));
}
}
(3)工程优势
- 依赖倒置:Service 依赖接口而非具体实现类
- 开闭原则:新增支付方式只需添加新的 Processor 实现和工厂分支
- 测试隔离:可通过 Mock 工厂返回测试对象
四、观察者模式:实现松耦合的事件通知
1. 原理与结构
(1)核心定义
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。
(2)结构组成
- Subject:主题接口,定义添加、删除和通知观察者的方法
- ConcreteSubject:具体主题,维护观察者列表,状态变化时通知观察者
- Observer:观察者接口,定义响应通知的方法
- ConcreteObserver:具体观察者,实现响应逻辑
2. 实战场景:订单状态变更通知(电商系统)
(1)场景分析
订单状态变更(如支付成功、发货、签收)需通知多个系统:库存系统、物流系统、消息推送系统等。
(2)核心代码实现
// 观察者接口
public interface OrderStatusObserver {
void update(Order order);
}
// 主题接口
public interface OrderStatusSubject {
void registerObserver(OrderStatusObserver observer);
void removeObserver(OrderStatusObserver observer);
void notifyObservers();
}
// 订单实现主题接口
public class Order implements OrderStatusSubject {
private List<OrderStatusObserver> observers = new ArrayList<>();
private OrderStatus status;
@Override
public void registerObserver(OrderStatusObserver observer) {
observers.add(observer);
}
@Override
public void removeObserver(OrderStatusObserver observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (OrderStatusObserver observer : observers) {
observer.update(this);
}
}
// 状态变更时通知观察者
public void setStatus(OrderStatus status) {
this.status = status;
notifyObservers();
}
}
// 库存系统观察者
public class InventoryObserver implements OrderStatusObserver {
private final InventoryService inventoryService;
@Override
public void update(Order order) {
if (order.getStatus() == OrderStatus.PAID) {
// 支付成功,扣减库存
inventoryService.reduceStock(order.getProductId(), order.getQuantity());
}
}
}
// 物流系统观察者
public class LogisticsObserver implements OrderStatusObserver {
private final LogisticsService logisticsService;
@Override
public void update(Order order) {
if (order.getStatus() == OrderStatus.SHIPPED) {
// 发货,创建物流单
logisticsService.createWaybill(order.getId());
}
}
}
// 客户端使用
public class OrderService {
public void payOrder(Long orderId) {
// 获取订单
Order order = orderRepository.findById(orderId);
// 注册观察者
order.registerObserver(new InventoryObserver(inventoryService));
order.registerObserver(new MessageObserver(messageService));
// 更新状态,自动触发通知
order.setStatus(OrderStatus.PAID);
}
}
(3)工程优势
- 松耦合:订单服务不直接依赖库存、物流等系统
- 可扩展性:新增通知系统只需实现 Observer 接口并注册
- 异步处理:可结合线程池实现异步通知,提升性能
五、设计模式的组合应用:解决复杂场景
1. 工厂 + 策略:动态选择算法(金融风控)
// 风险评估策略接口
public interface RiskStrategy {
RiskLevel assess(Transaction transaction);
}
// 高风险策略
public class HighRiskStrategy implements RiskStrategy {
@Override
public RiskLevel assess(Transaction transaction) {
// 高风险评估逻辑
}
}
// 策略工厂
public class RiskStrategyFactory {
public RiskStrategy createStrategy(Customer customer) {
if (customer.getAccountAge() < 30) {
return new HighRiskStrategy();
} else if (customer.getTransactionCount() > 100) {
return new LowRiskStrategy();
} else {
return new MediumRiskStrategy();
}
}
}
2. 责任链 + 观察者:复杂流程监控(医疗系统)
// 患者检查流程处理器
public abstract class PatientCheckHandler implements OrderStatusObserver {
protected PatientCheckHandler nextHandler;
public abstract boolean process(Patient patient);
public void setNextHandler(PatientCheckHandler nextHandler) {
this.nextHandler = nextHandler;
}
// 实现观察者接口,响应检查状态变更
@Override
public void update(Patient patient) {
if (canHandle(patient.getStatus())) {
boolean success = process(patient);
if (success && nextHandler != null) {
nextHandler.update(patient);
}
}
}
protected abstract boolean canHandle(PatientStatus status);
}
六、八年实战经验:设计模式的正确打开方式
1. 选型决策树
2. 实施原则
- 最小知识原则:每个模块只了解与其直接交互的模块
- 渐进式引入:先通过 Extract Method 重构,再引入模式
- 工具辅助:使用 UML 工具(如 PlantUML)设计模式结构
建议开发者从以下路径实践:
-
识别代码异味:如长方法、重复逻辑、紧耦合等
-
匹配对应模式:如条件判断多→策略模式,对象创建复杂→工厂模式
-
小步重构:先提取接口,再实现模式,最后替换调用点
记住:优秀的代码不是一次性写成的,而是通过持续重构和模式应用「进化」而来。当我们在代码中应用责任链处理流程、用工厂解耦创建、用观察者实现通知时,不仅是在提升代码质量,更是在培养对系统架构的洞察力。这才是八年设计模式实践带给我们最宝贵的财富 —— 让代码在变化中保持优雅,在演进中持续发光。