文章目录
1、常见场景
在支付成功回调方法中,往往需要对不同来源的订单做不同的处理;在积分兑换、抽奖等场景中,往往需要对不同类型的商品做不同的处理……此类场景最简单的实现方式是用if-else分支结构,然而随着业务不断增加,if-else分支结构会变得臃肿且难以维护,这时可以考虑使用策略模式实现。
2、示例代码
此处以订单支付成功后的回调处理为例,订单可以分为违章缴罚、六年免检、线上年审、驾驶证补换、行驶证补换等不同类型的订单,以及来源于微信公众号、微信小程序、电话营销、线上预约等不同的渠道。不同类型及不同渠道的订单都各自对应不同的后置处理逻辑。
2.1 订单类
@Data
public class Order {
//订单编号
private String orderId;
//订单名称
private String orderName;
//订单类型
private Integer orderType;
//渠道标识
private String channelTag;
//实收金额
private BigDecimal realAmount;
//其他字段……
}
2.2 订单类型枚举类
public enum OrderType {
WZJF(1,"违章缴罚"),
LNMJ(2,"六年免检"),
JSZBH(3,"驾驶证补换"),
XSZBH(4,"行驶证补换"),
XSNS(5,"线上年审"),
JYYYY(6,"警医邮预约");
private final Integer type;
private final String desc;
OrderType(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
public Integer getType() {
return type;
}
}
2.3 渠道枚举类
public enum Channel {
WXGZH("wxgzh","微信公众号"),
JFXCX("jfxcx","缴罚小程序"),
NSXCX("nsxcx","年审小程序"),
DHYX("dhyx","电话营销");
private final String tag;
private final String desc;
Channel(String tag, String desc) {
this.tag = tag;
this.desc = desc;
}
public String getTag() {
return tag;
}
}
2.4 订单支付后置处理适配器
定义一个统一的订单支付后置处理接口,后续不同类型、渠道的订单支付后置处理器皆实现此接口。
public interface OrderPayPostProcessAdapter {
void orderPayPostProcess(Order order);
}
2.5 订单处理器注解
定义一个订单处理器注解,用于订单支付后置处理器上。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OrderProcessor {
OrderType[] orderType();
Channel[] channel();
}
2.6 订单支付后置处理器持有器
定义一个订单支付后置处理器持有器,用于存放订单支付后置处理器,并提供一个获取订单支付后置处理器的方法。
public class OrderPayPostProcessorHolder {
private static final Map<String, OrderPayPostProcessAdapter> HOLDER = new HashMap<>();
public OrderPayPostProcessorHolder(List<OrderPayPostProcessAdapter> list) {
if (list != null && list.size() > 0){
for (OrderPayPostProcessAdapter orderPayPostProcessAdapter : list) {
OrderProcessor orderProcessor = AnnotationUtils.findAnnotation(orderPayPostProcessAdapter.getClass(), OrderProcessor.class);
if (orderProcessor != null){
OrderType[] orderTypeArr = orderProcessor.orderType();
Channel[] channelArr = orderProcessor.channel();
for (int i = 0; i < orderTypeArr.length; i++) {
for (int j = 0; j < channelArr.length; j++) {
//以orderType_channel作为key,如:1_wxgzh
String key = orderTypeArr[i].getType() + "_" + channelArr[j].getTag();
HOLDER.put(key, orderPayPostProcessAdapter);
}
}
}
}
}
}
public OrderPayPostProcessAdapter getOrderPayPostProcessor(Integer orderType, String channelTag){
String key = orderType + "_" + channelTag;
return HOLDER.get(key);
}
}
2.7 持有器配置类
把订单支付后置处理器持有器交给Spring容器管理。
@Configuration
public class HolderConfig {
@Bean
public OrderPayPostProcessorHolder orderPayPostProcessorHolder(List<OrderPayPostProcessAdapter> list){
return new OrderPayPostProcessorHolder(list);
}
}
2.7 订单服务类
@Service
public class OrderService {
@Autowired
private OrderPayPostProcessorHolder orderPayPostProcessorHolder;
/**
* 订单支付回调处理
* @param order
*/
public void orderPayPostProcess(Order order){
OrderPayPostProcessAdapter orderPayPostProcessor = orderPayPostProcessorHolder.getOrderPayPostProcessor(order.getOrderType(), order.getChannelTag());
if (orderPayPostProcessor != null){
orderPayPostProcessor.orderPayPostProcess(order);
}
}
}
2.8 订单支付回调后置处理器类
按照业务需要创建不同的订单支付回调后置处理器类
@Service
@OrderProcessor(orderType = {OrderType.WZJF, OrderType.LNMJ, OrderType.JSZBH, OrderType.XSZBH, OrderType.XSNS},
channel = {Channel.WXGZH, Channel.JFXCX, Channel.NSXCX})
public class OrderPayPostProcessor01 implements OrderPayPostProcessAdapter {
@Override
public void orderPayPostProcess(Order order) {
System.out.println("订单支付后置处理器1:处理普通订单……");
}
}
@Service
@OrderProcessor(orderType = {OrderType.JYYYY},channel = {Channel.DHYX})
public class OrderPayPostProcessor02 implements OrderPayPostProcessAdapter {
@Override
public void orderPayPostProcess(Order order) {
System.out.println("订单支付后置处理器2:处理电话营销渠道的警医邮预约订单……");
}
}
@Service
@OrderProcessor(orderType = {OrderType.XSNS},channel = {Channel.DHYX})
public class OrderPayPostProcessor03 implements OrderPayPostProcessAdapter {
@Override
public void orderPayPostProcess(Order order) {
System.out.println("订单支付后置处理器3:处理电话营销渠道的线上年审订单……");
}
}
2.9 测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestStrategy {
@Autowired
private OrderService orderService;
@Test
public void test1() throws Exception{
Order order = new Order();
order.setOrderId("202101010001");
order.setOrderName("缴罚小程序的违章缴罚订单(普通订单)");
order.setOrderType(OrderType.WZJF.getType());
order.setChannelTag(Channel.JFXCX.getTag());
orderService.orderPayPostProcess(order);
//print: 订单支付后置处理器1:处理普通订单……
}
@Test
public void test2() throws Exception{
Order order = new Order();
order.setOrderId("202101010002");
order.setOrderName("电话营销渠道的警医邮预约订单");
order.setOrderType(OrderType.JYYYY.getType());
order.setChannelTag(Channel.DHYX.getTag());
orderService.orderPayPostProcess(order);
//print:订单支付后置处理器2:处理电话营销渠道的警医邮预约订单……
}
@Test
public void test3() throws Exception{
Order order = new Order();
order.setOrderId("202101010003");
order.setOrderName("电话营销渠道的线上年审订单");
order.setOrderType(OrderType.XSNS.getType());
order.setChannelTag(Channel.DHYX.getTag());
orderService.orderPayPostProcess(order);
//print:订单支付后置处理器3:处理电话营销渠道的线上年审订单……
}
}