使用设计模式重构电商下单逻辑

使用工厂+策略模式重构创建订单逻辑,使用责任链默认计算订单价格等

0x01 现存问题

最初项目为了抢占市场快速迭代上线,遗留下来一堆的技术债务,其中以支付、下单等最为严重,无数的价格计算、营销活动(限时抢购、优惠券等等)、商品类型判断代码在一个接口中,造成后期维护成本巨大,其他人看起来费力,也没人敢改。

1
2
3
4
5
6
7
8
//解耦前的逻辑伪代码如下:
if (商品类型 == 限时抢购) {
限时抢购商品下单逻辑xxxx;
} else if (商品类型 == 普通商品) {
普通商品下单逻辑xxxx;
} else if (xxx = xxx) {
xx商品下单逻辑xxxx;
}

以上代码存在的几个问题:

  • 可读性差
    主干逻辑不清晰,不看上个把小时不知道这几百行代码做了什么。
  • 可扩展性差
    新增一种商品或者活动,要全面修改代码,不符合开闭原则。
  • 代码冗余度高
    同样的代码在每一种商品类型的逻辑处理中都写了一遍,修改的时候要修改三处。

我想要一个什么样的下单接口

  • 可读性好
    主干逻辑清晰,一目了然这个接口核心逻辑走了哪几步,每一步分别做了什么。
  • 可扩展性好
    后期加入一个商品或者加入一个活动,只需要新增代码,不需要修改历史代码。
  • 复用性强
    公共代码抽取出来,各个支付接口复用这部分代码,例如创建订单、价格计算、营销活动处理等。

0x02 重构方案

打算采用简单工厂 + 策略模式对不同商品、不同活动的下单逻辑进行解耦。

解耦后的下单逻辑uml图

strategy

使用不同的策略处理不同商品类型的下单逻辑,通用的计算运费扣减库存等都可以封装到抽象策略类中,后续增加其他营销活动都能保持对应业务的clean code;

0x03 Spring中策略的实现小技巧

简单工厂+策略模式,需要自己创建工厂。其实Spring可以帮我们做这一步。而且Spring本来就可以理解成是一个大的工厂;

1、策略实现类都加上注解@Component让Spring管理。
2、在使用的业务类中直接注入map就可以直接使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Autowired
private final Map<String, OrderStrategy> orderStrategyMap = new HashMap<>();

//使用方法,
//orderStrategyMap.get("normalOrderStrategy");
//策略实现类默认的key是类名第一个字母小写(Spring默认注入命名机制);

//当然我的用法是,将默认值直接写进抽象策略的常量,业务中直接使用常量,防止错误也更加清晰
if (limitPromotionFlag != null) {
orderStrategy = orderStrategyMap.get(OrderStrategy.LIMIT_ORDER_STRATEGY);
} else {
orderStrategy = orderStrategyMap.get(OrderStrategy.NORMAL_ORDER_STRATEGY);
}
Order order = orderStrategy.createOrder(xxx);

0x04 其他

使用责任链模式重构计算订单价格同理(优惠券,运费,折扣);