一、概念
策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
-
if else使用
if (pageLevel = "1") { // 发送get请求 } else if(pageLevel = "2") { // 发送post请求 } else { // }
这种if else代码块中,代码很难维护也很也不够美观,那么我们可以使用策略模式来处理这种情况。
二、案例
简单来讲就是定义一个接口,然后有多个实现类,每种实现类封装了一种行为。然后根据条件的不同选择不同的实现类。
-
抽象业务接口
public interface SendRequestCenter { public abstract void solve(String param); public abstract String[] supports(); }
-
接口实现类,举例:一个发送get请求,一个发送post请求
import org.springframework.stereotype.Component; @Component public class SendPostRequestSolver implements SendRequestCenter { @Override public void solve(String param) { System.out.println("参数是" + param + "的post请求已经发送了。。"); } @Override public String[] supports() { return new String[]{RequestType.HTTP_POST}; } }
import org.springframework.stereotype.Component; @Component public class SendGetRequestSolver implements SendRequestCenter { @Override public void solve(String id) { System.out.println("参数是" + id + "的get请求已经发送了。。"); } @Override public String[] supports() { return new String[]{RequestType.HTTP_GET}; } }
-
常量类
public class RequestType { public static String HTTP_GET = "1"; public static String HTTP_POST = "2"; }
-
将业务处理器和其支持处理的类型放到一个容器中,Map就是最常用的容器,使用spring的上下文存储信息
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; @Component public class RequestSolverChooser implements ApplicationContextAware { private ApplicationContext context; private Map<String, SendRequestCenter> chooseMap = new HashMap<>(); public SendRequestCenter choose(String type) { return chooseMap.get(type); } //被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。 //被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。 @PostConstruct public void register() { Map<String, SendRequestCenter> solverMap = context.getBeansOfType(SendRequestCenter.class); for (SendRequestCenter solver : solverMap.values()) { for (String support : solver.supports()) { chooseMap.put(support, solver); } } } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; } }
-
另一种处理方式是使用工厂模式和策略模式相结合,工厂采用单例模式
import java.util.HashMap; import java.util.Map; public class StrategyFactory { private static StrategyFactory factory = new StrategyFactory(); private StrategyFactory(){ } private static Map<String,SendRequestCenter> strategyMap = new HashMap<>(); static{ strategyMap.put(RequestType.HTTP_GET, new SendGetRequestSolver()); strategyMap.put(RequestType.HTTP_POST, new SendPostRequestSolver()); } public SendRequestCenter creator(String pType){ return strategyMap.get(pType); } public static StrategyFactory getInstance(){ return factory; } }
-
在单元测试中进行测试
@Autowired private RequestSolverChooser chooser; //使用spring上下文测试 @Test public void test() throws Exception { //准备数据 String taskType = RequestType.HTTP_GET; //获取任务类型对应的solver SendRequestCenter solver = chooser.choose(taskType); if (solver == null) { throw new RuntimeException("任务类型暂时无法处理!"); } //调用不同solver的方法进行处理 solver.solve("\"百度\""); } //使用工厂模式测试 @Test public void test2() throws Exception { String taskType = RequestType.HTTP_POST; SendRequestCenter solver = StrategyFactory.getInstance().creator(taskType); if (solver == null) { throw new RuntimeException("任务类型暂时无法处理!"); } //调用不同solver的方法进行处理 solver.solve("\"腾讯\""); }
-
测试结果1
2020-01-15 15:25:46.752 INFO 2120 --- [ main] c.w.collection.DemoApplicationTests : No active profile set, falling back to default profiles: default 2020-01-15 15:25:47.574 INFO 2120 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2020-01-15 15:25:47.766 INFO 2120 --- [ main] c.w.collection.DemoApplicationTests : Started DemoApplicationTests in 1.255 seconds (JVM running for 2.254) 参数是"百度"的get请求已经发送了。。 2020-01-15 15:25:47.923 INFO 2120 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
-
测试结果2
2020-01-15 15:26:30.860 INFO 4640 --- [ main] c.w.collection.DemoApplicationTests : No active profile set, falling back to default profiles: default 2020-01-15 15:26:31.689 INFO 4640 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2020-01-15 15:26:31.867 INFO 4640 --- [ main] c.w.collection.DemoApplicationTests : Started DemoApplicationTests in 1.274 seconds (JVM running for 2.273) 参数是"腾讯"的post请求已经发送了。。 2020-01-15 15:26:32.013 INFO 4640 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
参考博客:https://blog.csdn.net/qq_22343483/article/details/100195157
来源:CSDN
作者:wanglei_
链接:https://blog.csdn.net/qq_38932871/article/details/103995383