设计模式之策略模式
-
场景
一般情况下我们会想到使用if...else,如下代码。但是实际的业务场景肯定不止这四种,随着条件越来也来,代码就显得非常的臃肿和难以维护。(也可以使用switch来实现,这里就不赘述了)
-
package com.example.designpattern.celuemoshi.old; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author shkstart * @create 2021-07-11 22:16 */ @RestController @RequestMapping("/testController") public class TestController { @RequestMapping("/arithmetic02") public double arithmetic02(String arithmeticType, int startNum, int endNum) {//arithmetic算术 double result = 0.0; if (arithmeticType.equals("addition")) { result = startNum + endNum; } else if (arithmeticType.equals("subtraction")) { result = startNum - endNum; } else if (arithmeticType.equals("multiplication")) { result = startNum * endNum; } else { result = startNum / endNum; } System.out.println("====================>" + result); return result; } }
调用地址:http://localhost:8080/testController/arithmetic02?arithmeticType=addition&startNum=5&endNum=5
创建一个接口类:BaseHandler
-
package com.example.designpattern.celuemoshi.firstvesion; /** * @author shkstart * @create 2021-07-11 22:23 */ public interface BaseHandler { // public double result = 0.0; public double arithmetic(int startNum, int endNum); }
创建加减乘法四种业务对应的接口实现类
- 加法实现类
-
package com.example.designpattern.celuemoshi.firstvesion; import org.springframework.stereotype.Service; /** * @author shkstart * @create 2021-07-11 22:25 */ @Service("addition") public class AdditionHandler implements BaseHandler{ @Override public double arithmetic(int startNum, int endNum) { return startNum + endNum; } }
- 减法实现类
-
package com.example.designpattern.celuemoshi.firstvesion; import org.springframework.stereotype.Service; /** * @author shkstart * @create 2021-07-11 22:30 */ @Service("subtraction") public class SubtractionHandler implements BaseHandler { @Override public double arithmetic(int startNum, int endNum) { return startNum - endNum; } }
- 乘法实现类
-
package com.example.designpattern.celuemoshi.firstvesion; import org.springframework.stereotype.Service; /** * @author shkstart * @create 2021-07-11 22:31 */ @Service("multiplication") public class MultiplicationHandler implements BaseHandler{ @Override public double arithmetic(int startNum, int endNum) { return startNum * endNum; } }
- 除法实现类
-
package com.example.designpattern.celuemoshi.firstvesion; import org.springframework.stereotype.Service; /** * @author shkstart * @create 2021-07-11 22:32 */ @Service("division") public class DivisionHandler implements BaseHandler { @Override public double arithmetic(int startNum, int endNum) { return startNum / endNum; } }
Controller类代码,使用@Autowired将BaseHandler注入
-
package com.example.designpattern.celuemoshi.firstvesion; import javafx.application.Application; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Map; /** * @author shkstart * @create 2021-07-11 22:16 */ @RestController @RequestMapping("/testController2") public class TestController2 { @Autowired private Map<String,BaseHandler> handlerMap; @RequestMapping("/arithmetic") public double arithmetic02(String arithmeticType, int startNum, int endNum) {//arithmetic算术 BaseHandler baseHandler = handlerMap.get(arithmeticType); double arithmetic = baseHandler.arithmetic(startNum, endNum); return arithmetic; } }
调用地址:http://localhost:8080/testController2/arithmetic?arithmeticType=addition&startNum=5&endNum=5
@component注解会把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="",class=""/>,启动项目时加载到handlerMap中,下面通过debug调试查看
思考如果这种方法不可行,我们可以采用工厂模式来完成
定义枚举
package com.example.designpattern.celuemoshi.secondvesion.enmu; /** * @author shkstart * @create 2021-07-11 23:12 */ public enum ArithmeticEnum { addition("addition","com.example.designpattern.celuemoshi.firstvesion.AdditionHandler"), division("division","com.example.designpattern.celuemoshi.firstvesion.DivisionHandler"), multiplication("multiplication","com.example.designpattern.celuemoshi.firstvesion.MultiplicationHandler"), subtraction("subtraction","com.example.designpattern.celuemoshi.firstvesion.SubtractionHandler"); String type; String value; private ArithmeticEnum(String type, String value) { this.type = type; this.value = value; } public String getType() { return type; } public void setType(String type) { this.type = type; } public java.lang.String getValue() { return value; } public void setValue(String value) { this.value = value; } public static ArithmeticEnum getObj(java.lang.String type){ for (ArithmeticEnum e : ArithmeticEnum.values()) { if(type.equals(e.getType())){ return e; } } return null; } }
定义工厂类
package com.example.designpattern.celuemoshi.secondvesion; import com.example.designpattern.celuemoshi.firstvesion.BaseHandler; import com.example.designpattern.celuemoshi.secondvesion.enmu.ArithmeticEnum; /** * @author shkstart * @create 2021-07-11 23:08 * 使用工厂模式创建对象 */ public class StrategyFacade { public BaseHandler getStrategyType(String arithmeticType) throws ClassNotFoundException, IllegalAccessException, InstantiationException { ArithmeticEnum obj = ArithmeticEnum.getObj(arithmeticType); BaseHandler o = (BaseHandler) Class.forName(obj.getValue()).newInstance(); return o; } }
定义controller
package com.example.designpattern.celuemoshi.secondvesion; import com.example.designpattern.celuemoshi.firstvesion.BaseHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Map; /** * @author shkstart * @create 2021-07-11 22:16 */ @RestController @RequestMapping("/testController3") public class TestController3 { @RequestMapping("/arithmetic") public double arithmetic02(String arithmeticType, int startNum, int endNum) throws IllegalAccessException, InstantiationException, ClassNotFoundException {//arithmetic算术 StrategyFacade strategyFacade = new StrategyFacade(); BaseHandler strategyType = strategyFacade.getStrategyType(arithmeticType); double arithmetic = strategyType.arithmetic(startNum, endNum); return arithmetic; } }
调用地址:http://localhost:8080/testController3/arithmetic?arithmeticType=addition&startNum=5&endNum=5
- @component将所有的bean实例化到Spring中,是一个map格式,@component注解的属性值就是map的key。
- 使用设计模式完全避免了大量的if...else,代码看起来简洁,便于后期扩展和维护。
- 后期新增业务只需关注自己的业务点,不需要新增逻辑判断。
- 缺点就是需要创建很多的实现类。
本文来自博客园,作者:小陈子博客,转载请注明原文链接:https://www.cnblogs.com/cj8357475/p/15000194.html