~码铃薯~

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

说一下你在实际项目开发中都用到了哪些设计模式

重点展开 3~5 个

1. 策略模式 + 工厂模式

场景:
我在银行信用卡中心中还款的时候,对接了多家支付渠道,这个时候就使用到了策略模式+工厂模式。

做法:

public interface PayStrategy {
    PayResult pay(PayRequest request);
    String getPayType();
}

每个渠道一个实现类,交给 Spring 管理。再用一个工厂或路由:

@Component
public class PayStrategyFactory {
    private final Map<String, PayStrategy> strategyMap;

    public PayStrategyFactory(List<PayStrategy> strategies) {
        strategyMap = strategies.stream()
            .collect(Collectors.toMap(PayStrategy::getPayType, s -> s));
    }

    public PayStrategy get(String payType) {
        PayStrategy strategy = strategyMap.get(payType);
        if (strategy == null) throw new BizException("不支持的支付方式");
        return strategy;
    }
}

2. 责任链模式:风控、审批、参数校验

场景:
我在做信用卡还款的时候,Java后端校验逻辑:
1、借记卡持卡人姓名、证件类型、证件号码、手机号,必须与信用卡账户登记信息完全一致。不一致直接拦截。借记卡持卡人姓名、证件类型、证件号码、手机号,必须与信用卡账户登记信息完全一致。不一致直接拦截。
2、账户状态校验:是否冻结、挂失、注销等等。
3、借记卡的金额是否充足。
4、借记卡限额校验。
5、还款笔数校验。
6、黑灰名单校验。
等等。

做法:

public interface OrderCheckHandler {
    void check(OrderContext context);
    int order();
}

每个校验器实现接口,Spring 注入 List<OrderCheckHandler>,按 order() 排序后依次执行。也可以手动维护 next 指针。

3. 模板方法模式:数据同步 / 导入导出

场景:
在银行的时候,做数据入湖入仓的时候,要将表中的数据导出到文件中,因为每张表的数据都不一样,倒是最终结果都是导出到文件中,这个时候我们使用到了模板方法模式。

做法:

public abstract class AbstractSyncTask {
    public final void execute() {
        List<RawData> raw = fetch();
        List<BizData> data = convert(raw);
        validate(data);
        save(data);
        recordLog();
    }

    protected abstract List<RawData> fetch();
    protected abstract List<BizData> convert(List<RawData> raw);
    // 通用方法直接实现
}

4. 观察者模式:订单状态变更后的通知

场景:
我在做4A权限管理平台项目的时候,用户变更权限,这个时候我们会变更信息封装为事件,然后发送到缓存(R2M)中,使用的是spring框架的事件发送机制,这其实就是观察者模式的一种应用。

做法:
用 Spring 的 ApplicationEvent

publisher.publishEvent(new OrderPaidEvent(orderId));

各监听器处理自己的逻辑:

@EventListener
public void addPoints(OrderPaidEvent event) { ... }

@TransactionalEventListener(phase = AFTER_COMMIT)
public void sendMq(OrderPaidEvent event) { ... }

效果: 支付主流程只关注支付,后续动作解耦。
注意: 默认同步,耗时长可加 @Async;涉及事务要用 @TransactionalEventListener;分布式场景用 MQ。


5. 代理模式:AOP 日志、事务、权限

场景:
接口日志、耗时统计、事务、权限校验,如果每个方法手写,重复代码太多。

做法:
Spring AOP 底层就是动态代理:接口用 JDK 动态代理,类用 CGLIB。自定义注解 + 切面:

@Around("@annotation(com.xxx.Log)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    long start = System.currentTimeMillis();
    try {
        return pjp.proceed();
    } finally {
        log.info("cost={}", System.currentTimeMillis() - start);
    }
}
posted on 2026-09-19 16:51  ~码铃薯~  阅读(4)  评论(0)    收藏  举报