Bootstrap

策略模式+代理模式实现

背景

在业务处理的过程中,可能会遇到接收某些参数,通过参数来判断要走不同的逻辑,不同的策略,这时候就可以用到策略模式。
如果在策略执行之前或者之后需要有一些公共的操作,那么就通过代理模式来实现。
下面是实现的demo

demo

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 消息处理回执策略
 */

@Slf4j
@Getter
public enum DouBackStrategyEnum {

    //默认的校验回执类型,无需处理
    TAG_0("doNothingStrategy"),
    //订单创建
    TAG_100("createOrderStrategy"),
    //订单支付/确认
    TAG_101("paidOrderStrategy"),
    //订单取消
    TAG_106("canceledOrderStrategy"),
    //订单已支付,待处理
    TAG_110("tradePendingOrderStrategy"),
    ;

    private final String strategyClassName;

    DouBackStrategyEnum(String strategyClassName) {
        this.strategyClassName = strategyClassName;
    }

    public static DouBackStrategyEnum getEnum(String code){
        try {
            return DouBackStrategyEnum.valueOf(DouBackStrategyEnum.class, code);
        }catch (Exception e){
            log.info("无对应策略,只需要存储,使用默认类 TAG_0");
            return TAG_0;
        }

    }
}
/**
 * @author 
 * 这里的入参是我当前业务的对象,在真正使用中,需要替换为自己的业务对象data
 */
public interface DouBackStrategy {
    void execute(JSONObject data);
}
/**
 * @author 
 * 无处理逻辑的其他消息
 */
@Component
public class DoNothingStrategy implements DouBackStrategy {
    @Override
    public void execute(JSONObject data) {
        System.out.println("Do nothing strategy executed with data: " + data.toString());
    }
}
/**
 * @author 
 * 创建订单消息策略
 */
@Slf4j
@Component
public class CreateOrderStrategy implements DouBackStrategy {
    @Override
    public void execute(JSONObject data) {
        log.info("CreateOrderStrategy 订单创建处理逻辑 data:{}", JSON.toJSONString(data));
    }
}
/**
 * @author  
 * 用户支付消息执行策略
 */
@Slf4j
@Component
public class PaidOrderStrategy implements DouBackStrategy {

    @Override
    public void execute(JSONObject data) {
        log.info("PaidOrderStrategy 接收订单支付成功消息 data:{}", JSON.toJSONString(data));
    }
}
/**
 * @author 
 * @date 
 * 策略回执数据代理类
 */
@Slf4j
class DouBackStrategyProxy implements DouBackStrategy {

    //代理类中的注入 对象需要传进来,因为每个代理对象都是new的
    private final DouMessageService douMessageService;
    private final DouBackStrategy strategy;
    private final DistributeIdHelper distributeIdHelper;

    public DouBackStrategyProxy(DouBackStrategy strategy, DouMessageService douMessageService, DistributeIdHelper distributeIdHelper) {
        this.strategy = strategy;
        this.douMessageService = douMessageService;
        this.distributeIdHelper = distributeIdHelper;
    }

    @Override
    public void execute(JSONObject data) {
        // 在执行策略之前进行存储操作
        log.info("消息存入数据库 data: {}", JSONObject.toJSONString(data));
        long dateLong = System.currentTimeMillis();
        DouMessageEntity douMessageEntity = new DouMessageEntity();
        douMessageEntity.setId(distributeIdHelper.getSnowflakeId());
        douMessageService.save(douMessageEntity);
        // 执行策略
        strategy.execute(data);
    }
}
/**
 * @author 
 * 获取策略上下文
 */
@Slf4j
@Service
public class DouBackStrategyContext {
    private DouBackStrategy strategy;

    @Resource
    private StrategyFactory strategyFactory;

    public void setStrategy(DouBackStrategyEnum tag) {
        this.strategy = strategyFactory.createStrategy(tag);
    }

    public void executeStrategy(JSONObject data) {
        if (strategy != null) {
            strategy.execute(data);
        } else {
            log.error("策略为空, data:{}", data.toJSONString());
        }
    }
}

使用

    @Resource
    private DouBackStrategyContext douBackStrategyContext;

    @Override
    @PostMapping("/back")
    public void back(@RequestParam("param") String param) {
        JSONArray objects = JSONObject.parseArray(param);
        for (Object ob : objects) {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(ob));
            DouBackStrategyEnum tagEnum = DouBackStrategyEnum.getEnum("TAG_" + jsonObject.getString("tag"));
            douBackStrategyContext.setStrategy(tagEnum);
            douBackStrategyContext.executeStrategy(jsonObject);
        }
    }
;