策略模式
定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
我自己的理解就是通过接口实现不同的方法,同时又可以根据自己的选择自动选择使用哪个接口的实现。
情境:
某客户需要订购多个资源,每一个资源在不同的资源池下面,不同的资源池下面的资源又是不同的。由于不想使用多个if else来判断用户选择的资源池来进行资源的选择,所以使用了策略模式来实现结构上的优化。
环境:
基于SpringBoot实现的策略模式
DEMO:
用户在application中自由的选择任何资源池进行订购时,由context上下文进行判断选择资源去资源池调用,从而实现结构上的优化。
Strategy接口:
-
public interface Strategy {
-
String getVpcList(String id);
-
}
ResourceA实现:
-
@Component("A")
-
public class ResourceA implements Strategy {
-
@Override
-
public String getVpcList(String id) {
-
System.out.println("A,getVpcList ==========="+id);
-
return id;
-
}
-
}
ResourceB实现:
-
@Component("B")
-
public class ResourceB implements Strategy {
-
@Override
-
public String getVpcList(String id) {
-
System.out.println("B strategy"+"====="+id);
-
return id;
-
}
-
}
SimpleContext实现:
通过Spring将实现Strategy的实现类都自动注入到strategyMap类中,当用户传入选择的资源池时,自动根据资源池id去对应的资源池实现中查找资源。
-
@Service
-
public class SimpleContext {
-
@Autowired
-
private final Map<String, Strategy> strategyMap = new ConcurrentHashMap<>();
-
public SimpleContext(Map<String, Strategy> strategyMap) {
-
this.strategyMap.clear();
-
strategyMap.forEach((k, v)-> this.strategyMap.put(k, v));
-
}
-
public String getResource(String poolId){
-
return strategyMap.get(poolId).getVpcList(poolId);
-
}
-
}
Application实现:
-
@RestController
-
@RequestMapping("/test")
-
public class TestController {
-
@Autowired
-
private SimpleContext simpleContext;
-
@GetMapping("/choose")
-
public String choose(@RequestParam String poolId){
-
return simpleContext.getResource(poolId);
-
}
-
}
将SpringBoot工程跑起来,通过Postman进行测试。若是遇到404的情况或者500,请注意Application中进行注释包扫描路径:
-
@SpringBootApplication
-
@ComponentScan(basePackages = {"com.example.teststragy"})
-
public class TeststragyApplication {
-
public static void main(String[] args) {
-
SpringApplication.run(TeststragyApplication.class, args);
-
}
-
}
测试:
通过这个简单的demo,就可以看到通过在Postman输入不同的资源池id,可以自动的拿到不同的资源。
通过实践总结下来,使用策略模式的好处就是通过一个封装的上下文可以自由的切换不同的算法,省去多重判断,同时可以具有很好的扩展性。