设计模式工程落地
1. 这是什么
设计模式是对常见设计问题的经验总结。
工程落地的重点不是背名称,而是识别问题并选用合适的抽象方式。
一句话理解:
- 设计模式不是面试术语
- 它更像一组“面对常见变化点时的组织经验”
2. 为什么重要
设计模式能帮助系统更容易扩展和维护,但前提是用对场景。
真正高级的能力,是知道:
- 什么时候该抽象
- 什么时候不该抽象
用对了,代码会:
- 更可扩展
- 更易测试
- 更容易替换实现
用错了,则会变成:
- 过度设计
- 阅读成本高
- 维护负担重
3. 先建立直觉:先看变化点,再选模式
这是学习模式最关键的一步。
真正适合上模式的地方,通常都有某种稳定的变化点,例如:
- 算法会变
- 规则会变
- 流程中的某些节点会变
- 同一套主流程有多个变体
如果没有稳定变化点,却硬上抽象,最后往往只是:
- 多了一层类
- 没有真正收益
4. 核心内容
4.1 工厂模式
工厂模式适合:
- 创建逻辑有分支
- 对象创建过程不想散落在业务代码里
它的价值在于:
- 把“创建什么、怎么创建”集中管理
4.2 策略模式
策略模式适合:
- 同一件事有多种实现方式
- 可以按条件切换算法或规则
典型场景:
- 支付方式
- 计费方式
- 风控策略
4.3 模板方法
模板方法适合:
- 主流程固定
- 某些步骤允许子类覆写
它强调的是:
- 流程框架稳定
- 局部步骤可扩展
4.4 观察者模式
观察者模式适合:
- 一个事件发生后,需要通知多个订阅者
典型场景:
- 订单完成后通知积分、消息、日志、审计
4.5 责任链模式
责任链模式适合:
- 一组规则按顺序依次处理
- 每个节点只关心自己那一段判断或处理
典型场景:
- 参数校验链
- 风控检查链
- 过滤处理链
5. 学习重点
这一章最重要的是掌握:
- 先看问题,再选模式
- 模式的收益和成本要一起评估
- 策略模式适合“同类算法切换”
- 责任链适合“多步规则串联”
- 模板方法适合“主流程稳定、局部步骤可扩展”
6. 常见问题
6.1 为了模式而模式
这是最典型的误区。
如果模式没有真正解决变化点,最后只会增加复杂度。
6.2 抽象层次过多导致阅读成本上升
架构不是层数越多越高级。
6.3 没有稳定变化点却提前设计
这很容易把项目做成“过度工程化样板”。
7. 动手验证
这一节我用一个纯 Java demo,把策略模式和责任链模式放到后端业务场景里一起跑。
7.1 准备一个可运行示例
新建文件 DesignPatternDemo.java,内容如下:
java
import java.util.ArrayList;
import java.util.List;
public class DesignPatternDemo {
interface PriceStrategy {
int calc(int amount);
}
static class NormalPriceStrategy implements PriceStrategy {
@Override
public int calc(int amount) {
return amount;
}
}
static class VipPriceStrategy implements PriceStrategy {
@Override
public int calc(int amount) {
return amount - 20;
}
}
static class OrderPriceService {
private final PriceStrategy strategy;
OrderPriceService(PriceStrategy strategy) {
this.strategy = strategy;
}
int finalPrice(int amount) {
return strategy.calc(amount);
}
}
interface Validator {
void validate(OrderCommand command);
}
static class OrderCommand {
final long userId;
final int amount;
final String productCode;
OrderCommand(long userId, int amount, String productCode) {
this.userId = userId;
this.amount = amount;
this.productCode = productCode;
}
}
static class UserValidator implements Validator {
@Override
public void validate(OrderCommand command) {
if (command.userId <= 0) {
throw new IllegalArgumentException("invalid user");
}
System.out.println("validator-user-pass");
}
}
static class AmountValidator implements Validator {
@Override
public void validate(OrderCommand command) {
if (command.amount <= 0) {
throw new IllegalArgumentException("invalid amount");
}
System.out.println("validator-amount-pass");
}
}
static class ProductValidator implements Validator {
@Override
public void validate(OrderCommand command) {
if (command.productCode == null || command.productCode.isBlank()) {
throw new IllegalArgumentException("invalid product");
}
System.out.println("validator-product-pass");
}
}
static class ValidationChain {
private final List<Validator> validators = new ArrayList<>();
void add(Validator validator) {
validators.add(validator);
}
void validate(OrderCommand command) {
for (Validator validator : validators) {
validator.validate(command);
}
}
}
public static void main(String[] args) {
OrderPriceService normal = new OrderPriceService(new NormalPriceStrategy());
OrderPriceService vip = new OrderPriceService(new VipPriceStrategy());
System.out.println("normalPrice=" + normal.finalPrice(100));
System.out.println("vipPrice=" + vip.finalPrice(100));
ValidationChain chain = new ValidationChain();
chain.add(new UserValidator());
chain.add(new AmountValidator());
chain.add(new ProductValidator());
chain.validate(new OrderCommand(1L, 100, "BOOK"));
System.out.println("validationChainDone=true");
}
}7.2 编译并运行
bash
javac DesignPatternDemo.java
java DesignPatternDemo7.3 你应该观察到什么
输出应包含这些关键信息:
text
normalPrice=100
vipPrice=80
validator-user-pass
validator-amount-pass
validator-product-pass
validationChainDone=true7.4 每一行在验证什么
normalPrice=100、vipPrice=80:说明策略模式适合在不改主流程的前提下切换算法- 三条
validator-...-pass:说明责任链模式适合把多步规则拆成独立节点 validationChainDone=true:说明整条校验流程可以由链式结构统一组织
8. 练习建议
下面这些练习做完,这一章会更扎实:
- 在真实业务里找一个适合策略模式的场景
- 用责任链处理一组校验规则
- 总结常见模式在后端项目中的落地位置
- 复盘一次“模式用过头”的代码案例
9. 自测问题
- 为什么设计模式不能脱离场景使用?
- 策略模式和模板方法分别适合哪类问题?
- 什么情况下设计模式会变成过度设计?
- 责任链模式为什么适合规则校验场景?
10. 自测核对要点
如果你的回答能覆盖下面这些点,说明这一章基本掌握到位了:
- 模式应服务于变化点,而不是服务于炫技
- 策略模式适合算法切换
- 模板方法适合固定主流程下的局部扩展
- 责任链适合多步规则串联
- 过度抽象会直接增加系统复杂度