首页 > 其他分享 >优雅的消除if..else,这1条锦囊妙计千万别错过!!

优雅的消除if..else,这1条锦囊妙计千万别错过!!

时间:2024-01-10 23:00:48浏览次数:34  
标签:code String .. pay void 别错过 value else public

首先来看一个demo!!

publicinterface IPay {  
    void pay();  
}  

@Service
publicclass AliaPay implements IPay {  
     @Override
     public void pay() {  
        System.out.println("===发起支付宝支付===");  
     }  
}  

@Service
publicclass WeixinPay implements IPay {  
     @Override
     public void pay() {  
         System.out.println("===发起微信支付===");  
     }  
}  
  
@Service
publicclass JingDongPay implements IPay {  
     @Override
     public void pay() {  
        System.out.println("===发起京东支付===");  
     }  
}  

@Service
publicclass PayService {  
     @Autowired
     private AliaPay aliaPay;  
     @Autowired
     private WeixinPay weixinPay;  
     @Autowired
     private JingDongPay jingDongPay;  
    
   
     public void toPay(String code) {  
         if ("alia".equals(code)) {  
             aliaPay.pay();  
         } elseif ("weixin".equals(code)) {  
              weixinPay.pay();  
         } elseif ("jingdong".equals(code)) {  
              jingDongPay.pay();  
         } else {  
              System.out.println("找不到支付方式");  
         }  
     }  
}

PayService类根据不同的code,决定调用用不同的支付类(比如:aliaPay)的pay方法进行支付。

那如果支付方式越来越多,就需要改toPay方法的代码,增加新的if...else判断!!那么代码就会显得无比冗余!!

优雅的消除if..else,这1条锦囊妙计千万别错过!!_设计模式

那我们有啥好的办法可以优化这些代码呢?

我们先来看一下这个案例!!

首先定义一个注解。

@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
public@interface PayCode {  

     String value();    
     String name();  
}

在所有的支付类上都加上该注解

@PayCode(value = "alia", name = "支付宝支付")  
@Service
publicclass AliaPay implements IPay {  

     @Override
     public void pay() {  
         System.out.println("===发起支付宝支付===");  
     }  
}  

 
@PayCode(value = "weixin", name = "微信支付")  
@Service
publicclass WeixinPay implements IPay {  
 
     @Override
     public void pay() {  
         System.out.println("===发起微信支付===");  
     }  
} 

 
@PayCode(value = "jingdong", name = "京东支付")  
@Service
publicclass JingDongPay implements IPay {  
 
     @Override
     public void pay() {  
        System.out.println("===发起京东支付===");  
     }  
}

然后增加最关键的类:

@Service
publicclass PayService2 implements ApplicationListener<ContextRefreshedEvent> {  
 
     privatestatic Map<String, IPay> payMap = null;  
     
     @Override
     public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {  
         ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();  
         Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(PayCode.class);  
        
         if (beansWithAnnotation != null) {  
             payMap = new HashMap<>();  
             beansWithAnnotation.forEach((key, value) ->{  
                 String bizType = value.getClass().getAnnotation(PayCode.class).value();  
                 payMap.put(bizType, (IPay) value);  
             });  
         }  
     }  
    
     public void pay(String code) {  
        payMap.get(code).pay();  
     }  
}

我们获取打了PayCode注解的类,放到一个map中,map中的key就是PayCode注解中定义的value,跟code参数一致,value是支付类的实例。

这样,每次就可以每次直接通过code获取支付类实例,而不用if...else判断了。

注意:这种方式的code可以没有业务含义,可以是纯数字,只有不重复就行。

那么还有一种方法主要针对code是有业务含义的场景。

@Service
publicclass PayService3 implements ApplicationContextAware {   
     private ApplicationContext applicationContext;  
     privatestaticfinal String SUFFIX = "Pay";  

     @Override
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
        this.applicationContext = applicationContext;  
     }  

     public void toPay(String payCode) {  
         ((IPay) applicationContext.getBean(getBeanName(payCode))).pay();  
     }  

     public String getBeanName(String payCode) {  
         return payCode + SUFFIX;  
     }  
}

我们可以看到,aliaPay、weixinPay和jingDongPay,这些支付类bean的名称都是由code和后缀拼接而成!

这就要求支付类取名的时候要特别注意,前面的一段要和code保持一致。

调用的支付类的实例是直接从ApplicationContext实例中获取的,默认情况下bean是单例的,放在内存的一个map中,所以不会有性能问题。

当然实际项目开发中使用if...else判断的场景非常多,上面只是其中2种场景。

下面再列举一下其他常见的场景。

根据不同的数字返回不同的字符串

public String getMessage(int code) {  
     if (code == 1) {  
        return"成功";  
     } elseif (code == -1) {  
        return"失败";  
     } elseif (code == -2) {  
        return"网络超时";  
     } elseif (code == -3) {  
        return"参数错误";  
     }  
     thrownew RuntimeException("code错误");  
}

其实,这种判断没有必要,用一个枚举就可以搞定。

publicenum MessageEnum {  
     SUCCESS(1, "成功"),  
     FAIL(-1, "失败"),  
     TIME_OUT(-2, "网络超时"),  
     PARAM_ERROR(-3, "参数错误");  

     privateint code;  
     private String message;  

     MessageEnum(int code, String message) {  
         this.code = code;  
         this.message = message;  
     }  
   
     public int getCode() {  
        returnthis.code;  
     }  

     public String getMessage() {  
        returnthis.message;  
     }  
  
     public static MessageEnum getMessageEnum(int code) {  
        return Arrays.stream(MessageEnum.values()).filter(x -> x.code == code).findFirst().orElse(null);  
     }  
}

再把调用方法稍微调整一下

public String getMessage(int code) {  
     MessageEnum messageEnum = MessageEnum.getMessageEnum(code);  
     return messageEnum.getMessage();  
}

完美!!!

当然,还有很多其他的场景可以优化if...else,我再这里就不一一介绍了,感兴趣的朋友可以给我留言,一起探讨和研究一下。

最后说一句(求关注!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

标签:code,String,..,pay,void,别错过,value,else,public
From: https://blog.51cto.com/u_16502039/9187057

相关文章

  • 分享苹果共享证书 - 持续更新中...
     声明:所有苹果共享证书均来自网络整理共享日期:2024-01-09共享证书:ANBANGINSURANCELTD.下载地址:https://www.sharesign.cn/cert.html 共享日期:2024-01-07共享证书:VIETNAMPOSTSANDTELECOMMUNICATIONSGROUP-HOCHIMINHCITYTELECOMBRANCH下载地址:https://www.......
  • 我在工作一年时怎么都看不懂的编程写法,今天...
    作为一名程序员,你一定遇到或亲自写过这样的代码。有人将它形象的形容为shi山,或者被戏称为“面向保就业编程”。以下面这个代码为例,其中的问题也显而易见,当越来越多的条件判断时,代码会变得非常臃肿,难以维护。StringmediaType="blogger";if("lxf".equals(mediaType))......
  • MySQL 数据库归档工具pt-archive 与归档数据的安全存储 与 为什么每次归档都少数...
    DBA在日常的工作中,数据归档是DB人员工作中的必选项。这里有技术的因素和法律的因素,数据库中的业务在使用一段时间内,数据表中必然存在大量的过期的数据,这些数据将不在与当前的业务有关,同时这些数据的存在会影响当前一些SQL的执行的性能,所以从技术的角度需要进行数据的归档。从法......
  • 不愧是字节,这薪资....
    字节跳动按照岗位职级对工资区间进行划分,看看下面这个内部员工爆料的薪资收入。根据岗级,1-2到2-1都是属于执行岗,工作经验一般在五年以下,2-2以上研发岗位,能够拿到的年薪加上股权,差不过就超过一百万了。看到这个收入,很多同为高级研发,技术经理的同学,说不羡慕肯定是有点言不由衷的。下......
  • 接手了个项目,被if..else搞懵逼了
    项目会最终沦为屎山,但是作为一个有追求的研发,我们就应当从每个小的ifelse着手,至少让当前这个项目在你维护期间,让其发展成屎山的速度变慢一些,或者能替之前的老前辈还掉一些技术债才是最好的,各位小伙伴你们觉得呢?背景领导:“这个项目,今后就给你维护了啊,仔细点......
  • 求4,8,16,32....个向量的平均
    m=[[0]*np.array(e).shape[1]foriinrange(np.array(e).shape[0])]j=0ifnp.array(e).shape[0]%2==0:foriinrange(0,int(len(e)/2),2):print('-',i)m[j]=mean_(e[i],e[i+1])j+=1m=np.a......
  • 执行ipmitool命令的时候提示:Could not open device at /dev/ipmi0...
    1、问题:执行ipmitool命令的时候提示“Couldnotopendeviceat/dev/ipmi0or/dev/ipmi/0or/dev/ipmidev/0:Nosuchfileordirectory”2、诊断:缺少相关模块3、解决:更新ipmi的rpm包之后,需要加载模块[root@~]#yuminstallipmi*Loadedplugins:langpacks,produc......
  • 新火种AI|抖音对AIGC亮明牌!AI虚拟人带货或将面临最大危机...
    作者:小岩编辑:小迪12月19日,抖音官方发布了一则重要公告,宣布将严厉打击包括AIGC在内的6种新型违规行为。所谓AIGC,指的就是当下发展势头正劲的生成式人工智能。之所以要打击AIGC,其实是为了重点打击新型养号行为。抖音志在打击黑灰产,而AIGC造假成了绕不过去的“路障”。事实上,抖音此次......
  • 记录--try...catch知识补全
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助说到try...catch都觉得非常熟悉了,不就是用来捕捉代码块中的错误嘛,平时也用得比较多的。然而因为了解不够多,我的面试却栽在了一个简单的知识点上:try...catch只能捕捉到同步执行代码块中的错误。题目是:以下代码有错......
  • js一道try...catch的面试题
    说到try...catch都觉得非常熟悉了,不就是用来捕捉代码块中的错误嘛,平时也用得比较多的。然而因为了解不够多,我的面试却栽在了一个简单的知识点上:try...catch只能捕捉到同步执行代码块中的错误。题目是:以下代码有错吗?如果有错,应该如何改正?try{setTimeout(()=>{thrown......