策略模式极简代码实现,使用function接口减少类膨胀

175 阅读2分钟

具体实现

解决策略模式的类膨胀问题可以使用享元模式,这边直接用一个函数式接口解决,废话少说,直接上代码

首先是策略注册类,注册类作为策略模式的父类抽象类,只提供获取策略的方法,具体的策略实现方法使用抽象方法交给子类去实现。主要实现如下,使用一个value为函数式接口的hashmap来保存策略方法,map的key作为选择哪一个策略的参数。此demo中声明两个方法,饥饿了就罢工,饱了就干活。init方法中初始化了策略方法的map。策略的获取方法getStrategy,参数是传入的key,通过map的get方法获取相应key的方法,返回方法。

@Component
public abstract class StrategyRegister {
    @Resource
    private StrategyService strategyService;
    /**
     * 策略map
     * function保存key为参数,value为返回类型
     * */
    private Map<String, Function<Param,String>> functionList;
    //策略key
    private static final String hunger = "饥饿";
    private static final String full = "饱了";
    
    public abstract String work(Param param);
    public abstract String destroy(Param param);

    /**
     * 初始化方法map,后续有新增方法在此注册
     * */
    @PostConstruct
    private void init()
    {
        functionList = new HashMap<>(10);
        //如果吃饱了就工作
        functionList.put(full,e->strategyService.work(e));
        //饿了就罢工
        functionList.put(hunger,e->strategyService.destroy(e));
    }

    /**
     * 获取策略方法
     * @param param 通过此传入参数自动选择策略
     * @return 获取到的策略方法
     * */
    public Function<Param,String> getStrategy(StrategyParam param)
    {
        return functionList.get(param.getStrategy());
    }
}

接下来是策略的具体实现方法work和destroy

@Component
public class StrategyService extends StrategyRegister{

    @Override
    public String work(Param param)
    {
        return param.getName()+"开始工作";
    }

    @Override
    public String destroy(Param param)
    {
        return param.getName()+"罢工了!";
    }

}

controller方法如下

@RestController
public class StratrgyDemoController {
    @Autowired
    private StrategyService strategyService;
    /**
     * @param param 通过此传入参数自动选择策略
     * @return 策略响应信息
     * */
    @PostMapping("teststrategy")
    public String teststrategy(@RequestBody StrategyParam param)
    {
        Function<Param, String> strategy = strategyService.getStrategy(param);
        Param params = new Param();
        params.setName("张三");
        return strategy==null?"找不到对应策略":strategy.apply(params);
    }
}

测试功能

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述

如此就实现了一个极简的策略方法。比起相当重量级的普通策略模式来说方便很多,具体用法可自行扩展,实际运用中比这复杂很多。