23种设计模式之策略模式(springboot中应用)

接到一个任务,需求是用策略模式,编写保存接口。
该接口是在springboot上进行开发,我的设想就是该接口接收json数据,其中有表名字段,通过表名来选择不同的策略。后期如果有不同的开发者需要不同的保存策略(往不同的表上保存数据),则只需要写一个实现基础策略的类然后自定义自己的需求即可。(下图框框内的三个类)
23种设计模式之策略模式(springboot中应用)_第1张图片
其中的返回格式ResponseResult自定义,不需要和我一样。AddService将所有实现了基础策略接口的类都注入Map容器中,并提供根据表名到map中获取策略的方法getResource()。

 
@RestController
@RequestMapping("/erpAdd")
public class AddController {
    @Autowired
    private AddService addService;

    @RequestMapping("/add")
    public ResponseResult add(@RequestBody String parJson){
        ResponseResult res = new ResponseResult();

        JSONObject data = JSONObject.parseObject(parJson); 
        String dbName = data.getString("dbName");
        JSONObject parJson1 = data.getJSONObject("parJson"); 
        if(parJson.isEmpty()||dbName.isEmpty()){//参数校验
            res.setData("");
            res.setErrcode(1);
            res.setErrmsg("参数不能为空!");
            return res;
        } 
        dbName = dbName.toLowerCase();
        try {
            addService.getResource(dbName,parJson1);
            res.setData("");
            res.setErrcode(0);
            res.setErrmsg("保存成功!");
        }catch (Exception e){

            res.setData("");
            res.setErrcode(1);
            res.setErrmsg("保存失败!");
        }

        return res;
    }
}


/**
 * 上下文Context,将所有的策略类都注入到map中,
 */
@Service
public class AddService { 
    //使用线程安全的ConcurrentHashMap 公共接口
    private final Map<String, AddStrategy > strategyMap = new ConcurrentHashMap<>();
    //Autowired注解会自动将实现策略接口的 实现类注入到Map中,key就是自定义的Bean的名称,对应的是表名
    //spring容器会在类加载后自动注入这个方法的参数,并执行一遍方法。
    @Autowired
    public AddService(Map<String, AddStrategy > strategyMap){
        this.strategyMap.clear();
        strategyMap.forEach((k,v)-> this.strategyMap.put(k,v));//将所有的策略暴露出来
        //将key(即具体策略类中的component的名称)与具体策略类put到map中
    }
    public void getResource(String dbName, JSONObject parJson) throws Exception {
        strategyMap.get(dbName).add(parJson);
        //在map中根据表名找的对应的容器
    }
}

@Autowired作用在方法上,会在spring初始化后执行一次。lambda表达式中的 k 就是以下"具体策略类" @Component(“wdddb”) 中定义的名称。v 就是具体的策略类。


/**
 * 策略接口
 */
public interface AddStrategy {
    public void add(JSONObject parJson) throws Exception;
}

在这里插入代码片
/**
 * 具体策略类
 *
 */
@Component("wdddb")//注入spring中,容器统一管理,直接用表名做容器的名称,通过不同的表名调用具体的策略
public class WdddStrategy implements AddStrategy {
    @Autowired
    AddMapper addMapper;
    @Override
    @Transactional(timeout = 25, propagation = Propagation.REQUIRED)
    public void add(JSONObject parJson) throws Exception {

        String buyerNick = parJson.getString("buyer_nick");
        String title = parJson.getString("title");
        String type = parJson.getString("type"); 
        if("".equals(buyerNick)||"".equals(title)||"".equals(type)){//parJson必填字段校验
            throw new Exception();//有空字段,则抛给上一个
        }
        Wdddb wdddb = new Wdddb();
        wdddb.setBuyer_nick(buyerNick);
        wdddb.setTitle(title);
        wdddb.setType(type);
        addMapper.addWddd(wdddb);
    }
}
@Mapper
public interface AddMapper {
     void addWddd(@Param("wdddb")Wdddb wdddb);

    void addWdddmx(@Param("wdddmxb")Wdddmxb wdddmxb);
}

AddMapper.xml就不赘述了。其他的具体策略类也不写了。

参考:策略设计模式
示例代码
23种设计模式之策略模式(springboot中应用)_第2张图片
参考中的示例是要用new来实例化的,但是spring的IOC已经将对象的创建交给容器负责了,再使用老方法就是回去了。所以在AddService中把具体策略类的创建交给容器去创建,解耦,易扩展。但是也有缺点,就是需要把所有的具体策略都暴露出来。在小项目中用更加繁琐,只有在大项目多人协助开发的情况下,优点才有所体现。

你可能感兴趣的:(设计模式,设计模式,java,spring,spring,boot,bean)