基于反射实现对于某个参数的注入,从而减少过多的if判断
前情提要这里面引入了hutool的工具包来实现下方操作
起因由来因为某种原因在前期数据库设计的时候对某一个本应该是一对多的字段,并没有创建一对多的表
-
例子: 当创建用户钱包的时候可能会有多种状态,也许是用户支某宝账号也许是用户微某账号,还可能是建某银行卡或者招某银行卡
本应该在创建表的是时候我们应该进行一人对多个钱包,如下表
user_id | pay_type(1:微某; 2:支某宝; 3:建某银行卡; 4:招某银行卡) | pay_ detail |
---|---|---|
1 | 1 | 微某账号 |
1 | 2 | 支某宝 |
1 | 3 | 61xxxxxxxxxxxxx |
1 | 4 | 62xxxxxxxxxxxxx |
上表为本应该创建的数据库表,但是由于前期数据库设计的原因并没有创建成这个样子的表,而是变成了以下的样子
user_id | weix | alip | bank_card_j | bank_card_z |
---|---|---|---|---|
1 | 微某账号 | 支某宝账号 | 61xxxxx | 61xxxxx |
这是时候我们本应该的select语句就从最原始的
where pay_type = #{payType} and user_id = #{userId};
变成了
where user_id = #{userId};
导致的问题在于虽然同样只进行了一次查询但是查询出来结果之后,后者会导致我们要使用很多哥if判断来检查是由哪一种支付方式,以下是伪代码
-
先引入hutool的组件包为了方便这里引入了全部,如果怕其他的没有使用可以根据具体业务情况进行调整这里暂时对于hutool依赖不做太多赘述
<!-- hutool工具类全部具体版本请查询官方,这里使用的是5.6.2 --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.6.2</version> </dependency>
-
首先下方是钱包对象
/** * 用户钱包对象 user_coin * * @author 社畜阿藏 * @date 2021-09-15 */ @Data public class UserCoinTest { private static final long serialVersionUID = 1L; /** * 用户Id */ private Long userId; /** * 微某账号 */ private String weix; /** * 支某宝账号 */ private String alip; /** * 招某银行卡号 */ private String bankCardJ; /** * 建某银行卡号 */ private String bankCardZ; }
-
当我们取出钱包对象的时候理论上我们需要进行多次判断这里使用如下方代码
// 这里的type是前端传来的参数,表明使用哪种支付方式 String payAccount = null; if(ObjectUtil.equals(type,"1")){ payAccount = userCoinTest.getWeix(); } if(ObjectUtil.equals(type,"2")){ payAccount = userCoinTest.getAlip(); } if(ObjectUtil.equals(type,"3")){ payAccount = userCoinTest.getBankCardJ(); } if(ObjectUtil.equals(type,"4")){ payAccount = userCoinTest.getBankCardZ(); } //---------------------------------- // 接下来是对于pay的具体使用,这里看还好,但是当出现n个银行的情况下,最优选一定是更改表结构,但是对于这种老代码,讲究不敢动,是真的不敢动,毕竟你不知道谁还做了什么
-
那么接下来就是解决方案,首先创建对应的枚举对象
/** * 支付方式枚举 * * @author 社畜阿藏 * @Date 2021/9/15 */ public enum PayEnum { /** * 微某 */ WEIX("1", "getWeix"), /** * 支某宝 */ ALIP("2", "getAlip"), /** * 建某银行 */ J("3", "getBankCardJ"), /** * 招某银行 */ Z("4", "getBankCardZ"), /** * 啥也不是 */ NONE("0", null); private final String payType; private final String getMethod; PayEnum(String payType, String getMethod) { this.payType = payType; this.getMethod = getMethod; } public String getPayTpye() { return payType; } public String getMethod() { return getMethod; } public static PayEnum getEnumByPayType(String payType) { PayEnum[] currencyEnums = values(); for (PayEnum anEnum : currencyEnums) { if (ObjectUtil.equals(anEnum.getPayTpye(), payType)) { return anEnum; } } return NONE; } }
-
然后对于业务层进行改变
public String selectPayAccount(UserCoinTest userCoinTest, String type) { // 取对应参数的的支付枚举 PayEnum payEnum = PayEnum.getEnumByPayType(type); // 如果取到的数据是啥也不是的情况下抛出异常,这里为了方便使用特定的标识码,只为了演示 if (ObjectUtil.equals(payEnum, PayEnum.NONE)) { // 这里500是魔法值,阿里规范不建议使用魔法值,所以也只是为了演示效果 return "500"; } // 反射对userCoinTest取出对应的值并返回 return ReflectUtil.invoke(userCoinTest, payEnum.getMethod()); }
以上就是基于反射来实践, 当然不仅可以使get还可以是别的,可以根据情况进行举一反三