前面一篇文章中提到了策略模式的demo但没有实际进行项目的整合。
正好这两天做项目遇到了一个可以使用这个模式的需求。分享一下。
需求如下:
这是个在app进行的统计,每个项目都有这样的统计,统计每个用户在不同项目下订单的数量。
我的想法是每个项目给前端返回一个List<String>比如
“全部:111”
“通过:2”
“撤销:3”
因为每个项目的统计可能不一样,如果只是返回每个字段对应的数据的话app发版频率可能就比较频繁。
整体需求大概是这样。每个项目对应一个策略。
最原始的写法,区分不同的项目根据不同的项目Id在同一个接口里使用else If进行区别。效果如下:
if(projectId=1){
//获取魔筷订单统计
}else if(projectId=2){
//统计抖音订单数据
}else if(projectId=3){
//统计快手项目的统计
}
else if(projectId=4){
//统计刷脸订单统计
}
经过优化,如下:
只需要这一行代码就可以实现根据项目id执行不同的策略
我将这些策略放在了一个map里去维护,如果写在这个方法里去初始化map的话每次调用都会初始化一次,也会有很多不需要的初始化。于是我将数据放在了spring初始化的时候进行初始化策略
一些具体的代码如下:
策略上下文对象:
package com.leke.magicblockstar.service.impl;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
/**
* @classname ProjectCountContent
* @description
* @date 2020/5/30 9:51
* @created by weiwensi
*/
@Component
public class ProjectCountContent {
public List<String> getProjectCountContent(ProjectCount strategy,Integer merchantId){
if(strategy==null){
return Collections.EMPTY_LIST;
}
return strategy.getProjectCount(merchantId);
}
}
策略公共实现的接口:
package com.leke.magicblockstar.service.impl;
import java.util.List;
/**
* @classname ProjectCountInfo
* @description
* @date 2020/5/30 9:52
* @created by weiwensi
*/
public interface ProjectCount {
List<String> getProjectCount(Integer projectId);
}
获取魔筷项目的策略:
package com.leke.magicblockstar.service.impl.countstrategy;
import com.leke.magicblockstar.dao.MagicBlockStarOrderDao;
import com.leke.magicblockstar.model.EnumMagicBlockStar;
import com.leke.magicblockstar.service.impl.ProjectCount;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @classname MagicBlockStarStrategy
* @description
* @date 2020/5/30 9:54
* @created by weiwensi
*/
@Component
public class MagicBlockStarStrategy implements ProjectCount {
@Autowired
private MagicBlockStarOrderDao magicBlockStarOrderDao;
@Override
public List<String> getProjectCount(Integer merchantId) {
//魔筷星选 统计用户订单
//全部
Integer countAll = magicBlockStarOrderDao.coutAll(merchantId, null);
//已经通过
Integer pass = magicBlockStarOrderDao.coutAll(merchantId, EnumMagicBlockStar.MagicBlockStar.PASS.getCode());
//失败
Integer fail = magicBlockStarOrderDao.coutAll(merchantId, EnumMagicBlockStar.MagicBlockStar.FAIL.getCode());
List<String> projectCounList = new ArrayList<String>() {{
add("全部:"+countAll);
add("通过:"+pass);
add("撤销:"+fail);
}};
return projectCounList;
}
}
业务层的策略调用:
@Autowired
private ProjectCountContent projectCountContent;
@Override
public RestResult<List<String>> getCount(Integer projectId, Integer merchantId) {
return RestResult.success(this.projectCountContent.getProjectCountContent(InitMagicBlockStrategy.strategyMap.get(projectId), merchantId));
}
这样我只需要往根据map的key去真正执行通过上下文Content类去实例化不同策略,这里面最主要的还是Java的多态的知识。实例化对象由对象的具体实例去调用实现了他们父类接口的下子类的具体方法。
以上就是我在项目里的应用。很简单,还希望多多指教。