开关代码优化-代码可维护性优化
场景:最近开发的系统有两种模式,使用开关来控制.在系统设置模块的界面上设置了的一个开关,来修改数据库中的一个字段,系统中每次通过读取数据库中开关的值俩判断要走哪个逻辑
优化前:在各个模块的业务代码中,用到开关的地方都去读取数据库中开关的值.
优化前缺点:重复多次编写相同的代码,代码不好维护(比如现在要求换一个字段去判断开关的状态,则需要修改所有判断开关的代码)
优化思路:
(1)添加代理类,在代理类中实现开关的控制,在业务代码中只需要写各自的业务代码,不用关心开关的相关逻辑
(2)添加开关方法类,执行指定的Java方法
设计知识点:
(1)动态代理
(2)反射调用方法
优化抽象代码:
(1)创建开关方法接口,并在接口中定义执行的方法
package com.example.demo3.proxy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @version: V1.0 * @author: songyan * @className: SwitchFunction * @packageName: com.example.demo3.proxy * @description: 开关方法 * @date: 2021/2/8 13:05 */ public interface ISwitchFunction { Object run(Method method, Object obj, Object... arg) throws InvocationTargetException, IllegalAccessException ; }
(2)创建开关方法类,实现开关方法接口,重写run方法,实现执行指定方法的逻辑(这里使用到了反射)
package com.example.demo3.proxy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @version: V1.0 * @author: songyan * @className: SwitchFunction * @packageName: com.example.demo3.proxy * @description: * @date: 2021/2/8 13:10 */ public class SwitchFunction implements ISwitchFunction { @Override public Object run(Method method,Object obj, Object... arg) throws InvocationTargetException, IllegalAccessException { return method.invoke(obj,arg); } }
(3)创建代理类,实现对开关的判断(这里是通过聚合的方式实现的也可以用继承的方式)
package com.example.demo3.proxy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @version: V1.0 * @author: songyan * @className: SwitchFunction * @packageName: com.example.demo3.proxy * @description: 开关方法 * @date: 2021/2/8 13:06 */ public class SwitchFunctionProxy extends SwitchFunction { private ISwitchFunction switchFunction; SwitchFunctionProxy(ISwitchFunction switchFunction) { this.switchFunction = switchFunction; } @Override public Object run(Method method, Object obj, Object... arg) throws InvocationTargetException, IllegalAccessException { System.out.println("**** 代理执行:开关判断 ***"); Boolean flag = true; if (flag) { return super.run(method, obj, arg); } return null; } }
(4)编写工具类,这里是为了简化使用工厂执行相关方法的代码
package com.example.demo3.proxy; import java.lang.reflect.Method; /** * @version: V1.0 * @author: songyan * @className: SwitchFunctionUtil * @packageName: com.example.demo3.proxy * @description: 开关方法判断 * @date: 2021/2/8 14:14 */ public class SwitchFunctionUtil { public static Object run(Method method, Object obj, Object... arg) throws Exception { SwitchFunction switchFunction = new SwitchFunction(); SwitchFunctionProxy switchFunctionProxy = new SwitchFunctionProxy(switchFunction); return switchFunctionProxy.run(method, obj, arg); } }
(5)客户端(模拟系统业务中实际调用的代码)
package com.example.demo3.proxy; /** * @version: V1.0 * @author: songyan * @className: SwitchFunctionClient * @packageName: com.example.demo3.proxy * @description: 开关方法 * @date: 2021/2/8 13:44 */ public class SwitchFunctionClient { public static void sendReturn() { System.out.println("工单回执"); } public static void sendMessage() { System.out.println("发送普通消息"); } public static String meeting(String name) { System.out.println("会议状态修改;会议名称:::" + name); return name; } public static void main(String[] args) throws Exception { SwitchFunctionClient switchFunctionClient = new SwitchFunctionClient(); SwitchFunctionUtil.run(SwitchFunctionClient.class.getMethod("sendReturn", null), switchFunctionClient); SwitchFunctionUtil.run(SwitchFunctionClient.class.getMethod("sendMessage", null), switchFunctionClient); SwitchFunctionUtil.run(SwitchFunctionClient.class.getMethod("meeting", String.class), switchFunctionClient, "年会"); } }