策略模式和简单工厂-实际应用

工作 / java / 2022-11-07

策略模式和简单工厂-实际应用

代码存在多个if…else…的时候 使用 策略模式可以使代码整洁度上升

以下 以发送公众号模板信息为示例 编写策略模式 加 简单工厂的混合模式来改动

/**
 * @Description: 伪代码
 * @author: zwy
 * @date: 2022年09月14日 14:09
 */
@Service
@Log4j2
public class AImpl implements AService {
    @Autowired
    private WXhttp wXhttp;

    @Resource
    private B B;
    @Resource
    private C c;

    @Resource
    private D d;

    @Value("${appid}")
    private String subAppid;
    @Value("${appid}")
    private String appid;

    @Resource
    private WXservice wXservice;

    @Override
    public Result<?> send(String openid, String e, Integer integer, Date date) {
        Data data = null;
        if (ObjectUtil.equal(integer, 0)) {
            //结果一
            data = not(e, date);
        }
        if (ObjectUtil.equal(integer, 1)) {
            //结果二
            data = pass(e, date);
        }
        if (ObjectUtil.equal(integer, 2)) {
            //结果三
            data = notPass(e, date);
        }


        Miniprogram miniprogram = new Miniprogram();
        miniprogram.setPagepath("小程序访问页面");
        miniprogram.setAppid(appid);

        Mp_template_msg mp_template_msg = new Mp_template_msg();
        mp_template_msg.setTemplate_id("腾讯模板ID");
        mp_template_msg.setAppid(subAppid);
        mp_template_msg.setUrl("http://weixin.qq.com/download");
        mp_template_msg.setMiniprogram(miniprogram);
        mp_template_msg.setData(data);

        SendingUnifiedMessage sendingUnifiedMessage = new SendingUnifiedMessage();
        sendingUnifiedMessage.setTouser(openid);
        sendingUnifiedMessage.setMp_template_msg(mp_template_msg);


        JSONObject parse = JSONUtil.parseObj(sendingUnifiedMessage);

        log.info("发送实体类:{}", parse);
        JSONObject sub = wXhttp.sub(parse, B.getToken(REDIS_WIX));
        log.info("errcode:{}", sub.get("errcode"));
        if (ObjectUtil.notEqual(sub.get("errcode"), 0)) {
            wXservice.saveRedisToken();
            sub = wXhttp.sub(parse, B.getToken(REDIS_WIX));
        }
        log.info("发送数据:{}", sub);
        return Result.OK(sub);
    }

    /**
     * 结果一
     *
     * @param e
     * @return
     */
    private Data not(String e, Date date) {
        Data data = new Data();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        data.setFirst(new First().setValue("1"));
        data.setKeyword1(new Keyword1().setValue("1"));
        data.setKeyword2(new Keyword2().setValue(simpleDateFormat.format(date)));
        data.setKeyword3(new Keyword3().setValue("1"));
        data.setKeyword4(new Keyword4().setValue("1"));
        data.setRemark(new Remark().setValue("1!"));
        return data;
    }

    /**
     * 结果二
     *
     * @param e
     * @return
     */
    private Data pass(String e, Date date) {
        Data data = new Data();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        data.setFirst(new First().setValue("2"));
        data.setKeyword1(new Keyword1().setValue("2"));
        data.setKeyword2(new Keyword2().setValue(simpleDateFormat.format(date)));
        data.setKeyword3(new Keyword3().setValue("2"));
        data.setKeyword4(new Keyword4().setValue("2"));
        data.setRemark(new Remark().setValue("2!"));
        return data;
    }

    /**
     * 结果三
     *
     * @param e
     * @return
     */
    private Data notPass(String e, Date date) {
        Data data = new Data();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        data.setFirst(new First().setValue("3"));
        data.setKeyword1(new Keyword1().setValue("3"));
        data.setKeyword2(new Keyword2().setValue(simpleDateFormat.format(date)));
        data.setKeyword3(new Keyword3().setValue("3"));
        data.setKeyword4(new Keyword4().setValue("3"));
        data.setRemark(new Remark().setValue("3!"));
        return data;
    }
}

以上代码臃肿 if…else…多,阅读起来很简单,但是代码十分的不优雅。

下面开始改造 :

把结果一 、结果二、结果三 分别拆分,用一个接口类来代理

/**
 * &#064;Description:  工厂模式
 * &#064;author:  zwy
 * &#064;date:  2022年11月07日 10:02
 */
public interface DateService {
    Data getDate(JSONObject jsonObject);
}

以下是 工厂类的实现

image-20221107170247338

下面是具体实现的逻辑(就是把之前的 结果一 结果二 结果三 从方法 变成类实现):

/**
 * &#064;Description:  策略模式 结果一  
 * &#064;author:  zwy
 * &#064;date:  2022年11月07日 10:03
 */
public class NotServiceImpl  implements DateService {
    @Override
    public Data getDate(JSONObject jsonObject) {
      	// 业务逻辑处理
        Data data = new Data();
        return data;
    }
}
/**
 * &#064;Description:  策略模式 结果二
 * &#064;author:  zwy
 * &#064;date:  2022年11月07日 10:03
 */
public class NotPassServiceImpl implements DateService {
    @Override
    public Data getDate(JSONObject jsonObject) {
      	// 业务逻辑处理
        Data data = new Data();
        return data;
    }
}
/**
 * &#064;Description:  策略模式 结果三
 * &#064;author:  zwy
 * &#064;date:  2022年11月07日 10:03
 */
public class PassServiceImpl implements DateService {
    @Override
    public Data getDate(JSONObject jsonObject) {
      	// 业务逻辑处理
        Data data = new Data();
        return data;
    }
}

下面就到 策略模式登场了 用到了 策略模式 加 map字典 来减少 if…else…的调度

/**
 * @Description: 策略实现类
 * @author: zwy
 * @date: 2022年11月07日 10:09
 */
public class DateStrategy {
    private static final Map<String, DateService> map = new HashMap<>();
    static {
        map.put("1.0",new NotServiceImpl());
        map.put("1.1",new PassServiceImpl());
        map.put("1.2",new NotPassServiceImpl());
    }

    public Data strategy(JSONObject jsonObject, DateService dateService) {
        return dateService.getDate(jsonObject);
    }

    public Data strategy(JSONObject jsonObject){
        return  strategy(jsonObject,map.get(jsonObject.getStr("type")));
    }

}

后续新业务到来后 只需要 添加 DateStrategy 的静态模块 添加对应规则 和 新创建 DateService 的实现类 即可 ,非常简单。

感谢查询!