优化if-else代码的八种方案

共 1753字,需浏览 4分钟

 ·

2020-03-09 23:23

前言

代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案。

2909e27d676c99a93242be1141729346.webp

优化方案一:提前return,去除不必要的else

如果if-else代码块包含return语句,可以考虑通过提前return,把多余else干掉,使代码更加优雅。

优化前:

  1. if(condition){

  2. //doSomething

  3. }else{

  4. return;

  5. }

优化后:

  1. if(!condition){

  2. return;

  3. }

  4. //doSomething

优化方案二:使用条件三目运算符

使用条件三目运算符可以简化某些if-else,使代码更加简洁,更具有可读性。

优化前:

  1. int price ;

  2. if(condition){

  3. price =80;

  4. }else{

  5. price =100;

  6. }

优化后:

  1. int price = condition?80:100;

优化方案三:使用枚举

在某些时候,使用枚举也可以优化if-else逻辑分支,按个人理解,它也可以看作一种表驱动方法

优化前:

  1. StringOrderStatusDes;

  2. if(orderStatus==0){

  3. OrderStatusDes="订单未支付";

  4. }elseif(OrderStatus==1){

  5. OrderStatusDes="订单已支付";

  6. }elseif(OrderStatus==2){

  7. OrderStatusDes="已发货";

  8. }

  9. ...

优化后:

先定义一个枚举

  1. publicenumOrderStatusEnum{

  2. UN_PAID(0,"订单未支付"),PAIDED(1,"订单已支付"),SENDED(2,"已发货"),;


  3. privateint index;

  4. privateString desc;


  5. publicint getIndex(){

  6. return index;

  7. }


  8. publicString getDesc(){

  9. return desc;

  10. }


  11. OrderStatusEnum(int index,String desc){

  12. this.index = index;

  13. this.desc =desc;

  14. }


  15. OrderStatusEnum of(int orderStatus){

  16. for(OrderStatusEnum temp :OrderStatusEnum.values()){

  17. if(temp.getIndex()== orderStatus){

  18. return temp;

  19. }

  20. }

  21. returnnull;

  22. }

  23. }

有了枚举之后,以上if-else逻辑分支,可以优化为一行代码

  1. StringOrderStatusDes=OrderStatusEnum.0f(orderStatus).getDesc();

优化方案四:合并条件表达式

如果有一系列条件返回一样的结果,可以将它们合并为一个条件表达式,让逻辑更加清晰。

优化前

  1. double getVipDiscount(){

  2. if(age<18){

  3. return0.8;

  4. }

  5. if("深圳".equals(city)){

  6. return0.8;

  7. }

  8. if(isStudent){

  9. return0.8;

  10. }

  11. //do somethig

  12. }

优化后

  1. double getVipDiscount(){

  2. if(age<18||"深圳".equals(city)||isStudent){

  3. return0.8;

  4. }

  5. //doSomthing

  6. }

优化方案五:使用 Optional

有时候if-else比较多,是因为非空判断导致的,这时候你可以使用java8的Optional进行优化。

优化前:

  1. String str ="jay@huaxiao";

  2. if(str !=null){

  3. System.out.println(str);

  4. }else{

  5. System.out.println("Null");

  6. }

优化后:

  1. Optional<String> strOptional =Optional.of("jay@huaxiao");

  2. strOptional.ifPresentOrElse(System.out::println,()->System.out.println("Null"));

优化方案六:表驱动法

表驱动法,又称之为表驱动、表驱动方法。表驱动方法是一种使你可以在表中查找信息,而不必用很多的逻辑语句(if或case)来把它们找出来的方法。以下的demo,把map抽象成表,在map中查找信息,而省去不必要的逻辑语句。

优化前:

  1. if(param.equals(value1)){

  2. doAction1(someParams);

  3. }elseif(param.equals(value2)){

  4. doAction2(someParams);

  5. }elseif(param.equals(value3)){

  6. doAction3(someParams);

  7. }

  8. // ...

优化后:

  1. MapFunction action> actionMappings =newHashMap<>();// 这里泛型 ? 是为方便演示,实际可替换为你需要的类型


  2. // 初始化

  3. actionMappings.put(value1,(someParams)->{ doAction1(someParams)});

  4. actionMappings.put(value2,(someParams)->{ doAction2(someParams)});

  5. actionMappings.put(value3,(someParams)->{ doAction3(someParams)});


  6. // 省略多余逻辑语句

  7. actionMappings.get(param).apply(someParams);

优化方案七:优化逻辑结构,让正常流程走主干

优化前:

  1. publicdouble getAdjustedCapital(){

  2. if(_capital <=0.0){

  3. return0.0;

  4. }

  5. if(_intRate >0&& _duration >0){

  6. return(_income / _duration)*ADJ_FACTOR;

  7. }

  8. return0.0;

  9. }

优化后:

  1. publicdouble getAdjustedCapital(){

  2. if(_capital <=0.0){

  3. return0.0;

  4. }

  5. if(_intRate <=0|| _duration <=0){

  6. return0.0;

  7. }


  8. return(_income / _duration)*ADJ_FACTOR;

  9. }

将条件反转使异常情况先退出,让正常流程维持在主干流程,可以让代码结构更加清晰。

优化方案八:策略模式+工厂方法消除if else

假设需求为,根据不同勋章类型,处理相对应的勋章服务,优化前有以下代码:

  1. String medalType ="guest";

  2. if("guest".equals(medalType)){

  3. System.out.println("嘉宾勋章");

  4. }elseif("vip".equals(medalType)){

  5. System.out.println("会员勋章");

  6. }elseif("guard".equals(medalType)){

  7. System.out.println("展示守护勋章");

  8. }

  9. ...

首先,我们把每个条件逻辑代码块,抽象成一个公共的接口,可以得到以下代码:

  1. //勋章接口

  2. publicinterfaceIMedalService{

  3. void showMedal();

  4. String getMedalType();

  5. }

我们根据每个逻辑条件,定义相对应的策略实现类,可得以下代码:

  1. //守护勋章策略实现类

  2. publicclassGuardMedalServiceImplimplementsIMedalService{

  3. @Override

  4. publicvoid showMedal(){

  5. System.out.println("展示守护勋章");

  6. }

  7. @Override

  8. publicString getMedalType(){

  9. return"guard";

  10. }

  11. }

  12. //嘉宾勋章策略实现类

  13. publicclassGuestMedalServiceImplimplementsIMedalService{

  14. @Override

  15. publicvoid showMedal(){

  16. System.out.println("嘉宾勋章");

  17. }

  18. @Override

  19. publicString getMedalType(){

  20. return"guest";

  21. }

  22. }

  23. //VIP勋章策略实现类

  24. publicclassVipMedalServiceImplimplementsIMedalService{

  25. @Override

  26. publicvoid showMedal(){

  27. System.out.println("会员勋章");

  28. }

  29. @Override

  30. publicString getMedalType(){

  31. return"vip";

  32. }

  33. }

接下来,我们再定义策略工厂类,用来管理这些勋章实现策略类,如下:

  1. //勋章服务工产类

  2. publicclassMedalServicesFactory{


  3. privatestaticfinalMap<String,IMedalService> map =newHashMap<>();

  4. static{

  5. map.put("guard",newGuardMedalServiceImpl());

  6. map.put("vip",newVipMedalServiceImpl());

  7. map.put("guest",newGuestMedalServiceImpl());

  8. }

  9. publicstaticIMedalService getMedalService(String medalType){

  10. return map.get(medalType);

  11. }

  12. }

使用了策略+工厂模式之后,代码变得简洁多了,如下:

  1. publicclassTest{

  2. publicstaticvoid main(String[] args){

  3. String medalType ="guest";

  4. IMedalService medalService =MedalServicesFactory.getMedalService(medalType);

  5. medalService.showMedal();

  6. }

  7. }




推荐阅读:


8eae1df6947cde9e86c2c6fe6ee98376.webp喜欢我可以给我设为星标哦8eae1df6947cde9e86c2c6fe6ee98376.webp

e691ed7f2d39814166438450111074fc.webp

好文章,我 在看 

7604c378559edbc57174a630ec44444c.webp
浏览 12
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报