首页 > 其他分享 >你有被if-else支配过吗?看完这篇文章,你就知道该怎么做

你有被if-else支配过吗?看完这篇文章,你就知道该怎么做

时间:2024-01-17 15:11:25浏览次数:21  
标签:支配 return BigDecimal 代码 else 篇文章 type public

在日常工作中,如果让你碰到一大堆if-else嵌套的代码,你会怎么做?

背景

最近在给之前负责的项目做CR的时候,在项目代码中发现有大量的if-else判断语句,阅读起来非常的折磨人而且也不利于后期的维护扩展,比较容易出问题。当时我直接气血上涌,差点昏过去。 缓过几分钟之后,把写这段代码的小张叫了过来,准备跟他好好聊聊。

我: 这块业务代码怎么这么多if-else语句判断,为什么要这么写?有没有想过代码规范或者该怎么去优化这段代码?
小张: 我根据自己对需求的理解,就直接上手写代码了,也没考虑过代码规范这些东西。

好嘛,年轻人到底是年轻人,做事情还得慢慢教。好好看好好学,下次再写代码时多注意代码规范,应当要避免此类问题。

教学时间开始

提前终止不符合的条件

首先,相信大部分小伙伴在写业务代码时,需要去做一些条件的校验(别告诉我你不做),就像下面的这段代码:

  private static void handleValueByDto(Dto dto) {
    if (flagA) {
       A a = handleMethodA(dto); 
       if (flagB) {
         B b = handleMethodB(a);
       }
    }
  }

这段代码看上去还行,那么假如在来几个if嵌套呢,要蚌埠住了吧?那么要怎么做呢?你可以这么去做,将不符合的条件提前终止,符合条件的继续处理,就像下面这段代码:

  private static void handleValueByDto(Dto dto) {
    if (!flagA) {
       // 这里可以加上日志,方便后续排查
       return;
    }
    A a = handleMethodA(dto); 
    if (!flagB) {
       // 这里可以加上日志,方便后续排查
       return;
    }
    B b = handleMethodB(a);
  }

优化过后的代码看上去更加优雅,而且也不会让人血压飙升。

三目运算符赋值

三目运算符我在日常工作中也经常用到,一方面可以将代码精简到一行,减少代码量,另外一方面,使用三目运算符更容易让别人理解。比如说:

A a = new A();
a.setGroup(StringUtils.isBlank(s) ? "1" : "2")

使用Optional解决判空

如果代码中某个属性值需要做判空处理,那么在Java8之后的版本,你可以使用Optional来处理,也能够避免大量的if-else语句。比如说:

  public static String handleValueByDto(String a) {
    if (a != null) {
        handleMethod(a);
    } else {
       return null;
    }
  }
  
  或者是
  public static String handleValueByDto(String a) {
    if (a == null) {
        return null;
    }
    handleMethod(a);
  }

上面的第二部分代码貌似也能接受,不过有更好的解决方案为何不用呢?

  public static String handleValueByDto(String a) {
    return Optional.ofNullable(a)
          .map(v -> handleMethod(a)).orElse(null);
  }

经过这么一对比,你更愿意用哪一种方案来解决判空呢?

使用枚举来优化

根据枚举值执行不同的操作,这一点针对if-else也能起到很不错的效果,具体操作如下:

  public enum HandleTypeEnum {
      TYPE_A(1) {
        protected Byte getHandle() {
           return 1;
        }
      },
      TYPE_B(2) {
        protected Byte getHandle() {
           return 2;
        }
      },
      TYPE_C(3) {
        protected Byte getHandle() {
           return 3;
        }
      };
      public Byte type;
      HandleTypeEnum(Byte type) {this.type = type;}
      
      public static HandleTypeEnum handleByType(Byte type) {
        return Arrays.stream(HandleTypeEnum.values())
               .filter(a -> a.type.equals(type))
               .findFirst().orElse(null);
      }
      
      protected abstract Byte getHandle();
  }
  
  private static Byte getHandle(Byte type) {
      HandleTypeEnum handleType = HandleTypeEnum.handleByType(type);
      return handleType.getHandle();
  }

使用Map

使用Map来优化if-else要注意的是,创建一个额外的map会占用服务内存,并且需要考虑清楚是否要使用这种方式来进行优化。实现方式比较简单,像下面这段代码:

  public static final Map<String, String> handleMap = ImmutableMap.<String, String>builder()
    .put("A", "处理A")
    .put("B", "处理B")
    .put("C", "处理C")
    .build();

使用的时候也非常简单,就是直接通过定义的map根据key获取相应的处理方法,例如:

  public String handleByType(String type) {
      return handleMap.get(type);
  }

策略模式

这个方案我在之前做过的项目中有使用过,具体操作就是将每一个条件单独抽离成一个策略类,在主业务流程中使用策略类执行相关逻辑。这种方案的好处就是能够降低代码耦合,比较利于后续维护以及业务扩展,并且也容易被理解。 比如说,电商系统下单业务,会涉及到不同的折扣方案,根据对应的折扣方案实现折扣减免,那么使用策略模式该怎么做呢?先定义一个策略接口

  public interface CouponDiscount<T> {
    /**
     * 判断该策略是否支持
     */
    Boolean support(BigDecimal price);
    BigDecimal discountAmount(BigDecimal skuPrice, T coupon);
  }

然后根据具体的折扣方案实现上面的策略接口:

  public class ACouponDiscount implements CouponDiscount<Double> {
  
      public Boolean support(BigDecimal price) {
          return price < 300;
      }
      public BigDecimal discountAmount(BigDecimal skuPrice, Double coupon) {
        // TODO: 实现折扣A业务处理逻辑
      }
  }
  
  public class BCouponDiscount implements CouponDiscount<Double> {
  
      public Boolean support(BigDecimal price) {
          return price > 500;
      }
      public BigDecimal discountAmount(BigDecimal skuPrice, Double coupon) {
        // TODO: 实现折扣B业务处理逻辑
      }
  }

最终调用模块中进行简单配置:

  public class CouponDiscountService {
      @Autowired
      private static List<CouponDiscount> list;
      public BigDecimal discountAmount(int type, double coupon, double skuPrice) {
          for (CouponDiscount v : list) {
              // 这里如果满足条件, 那么就使用该策略,不满足继续循环
              if (v.support(skuPrice)) {
                  return v.discountAmount(skuPrice, coupon)
              }
          }
      }
  }

我也注意到网上有非常多的文章在讲策略模式+工厂模式解决if-else的问题,但那种方式的前提是,明确知道有哪些策略存在。并且如果后续增加其它策略,意味着要改动策略工厂的代码,违背了开闭原则,所以不是很好。

最后总结

上面的几种方案在优化if-else方面有非常不错的效果,根据实际情况选择对应的方案来处理。不过最重要的一点就是,在编码阶段需要注意开发规范,尽量减少大量的if-else语句出现,避免给自己以及其他阅读代码的人带来困扰(说的是你,小张)。

如果这篇文章有给您带来帮助或者对这篇文章比较感兴趣,麻烦给点一个免费的关注。

谢谢,再会~~

标签:支配,return,BigDecimal,代码,else,篇文章,type,public
From: https://www.cnblogs.com/c-shallow-dream/p/17970061

相关文章

  • Python随笔3(流程控制if else )
    #answer=input('你是会员名y/n')##pass是空语句#if(answer=='y'):#pass#else:#pass'''只要是空的就是False'''print(bool(False))print(bool(0))print(bool(0.0))print(bool(None))print(bool(''))......
  • 【JaveWeb教程】(2)Web前端基础:JavaScript入门不再难:一篇文章教你轻松搞定JavaScript的
    目录1介绍2引入方式3基础语法3.1书写语法3.2变量3.3数据类型和运算符4函数4.1第一种定义格式4.2第二种定义格式html完成了架子,css做了美化,但是网页是死的,我们需要给他注入灵魂,所以接下来我们需要学习JavaScript,这门语言会让我们的页面能够和用户进行交互。1介绍通过代......
  • 【JaveWeb教程】(1)Web前端基础:HTML+CSS入门不再难:一篇文章教你轻松搞定HTML与CSS!
    目录1.前端开发介绍2.HTML&CSS2.1HTML快速入门2.1.1操作2.1.2总结2.2开发工具2.3基础标签&样式2.3.1新浪新闻-标题实现2.3.1.1标题排版2.3.1.1.1分析2.3.1.1.2标签2.3.1.1.2实现2.3.1.2标题样式2.3.1.2.1CSS引入方式2.3.1.2.2颜色表示2.3.1.2.3标题字体颜色2.......
  • 干掉过多的 if else,让你的代码更优雅
    干掉过多的ifelse,让你的代码更优雅学习改变命运,技术铸就辉煌。大家好,我是銘,全栈开发程序员。写代码时候,有时候条件过多,会有很多ifelse,代码看起来很乱,不够优雅,那如何让代码更优雅呢,如何让代码可读性更强呢,那銘哥就来教你怎么做。注意啊,是过的if-else,如果只是三四个,那就没必......
  • 干掉过多的 if else,让你的代码更优雅
    干掉过多的ifelse,让你的代码更优雅学习改变命运,技术铸就辉煌。大家好,我是銘,全栈开发程序员。写代码时候,有时候条件过多,会有很多ifelse,代码看起来很乱,不够优雅,那如何让代码更优雅呢,如何让代码可读性更强呢,那銘哥就来教你怎么做。注意啊,是过的if-else,如果只是三四个,那......
  • Java小细节之缩进中if 和else的对应关系
    importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){Scannerin=newScanner(System.in);System.out.print("请输入数字:");intn=in.nextInt();System.out.print("请输入分数:");intcount=in.nextInt();if(n==......
  • 优雅的消除if..else,这1条锦囊妙计千万别错过!!
    首先来看一个demo!!publicinterfaceIPay{voidpay();}@ServicepublicclassAliaPayimplementsIPay{@Overridepublicvoidpay(){System.out.println("===发起支付宝支付===");}}@ServicepublicclassWeixinPayim......
  • 上岸米哈游!一篇文章教你写好简历
    前言最近看到牛客上许多同学晒简历求助修改,自己也刚刚结束秋招,幸运上岸。本文将从简历模板选择开始,指导各位同学如何写出令hr满意的简历。一年前我在自己的博客里就写过类似的文章:一篇文章教你写好自己的简历,时隔一年我自己的简历也迭代了n次,就再出一期2.0的教程,怎么写简......
  • 软件测试/测试开发/全日制|pytest用例执行顺序,这篇文章就够了
    前言在使用unittest测试框架执行测试时,测试用例执行的顺序是默认按照ACSII码的顺序加载测试用例并执行,顺序为:0-9、A-Z、a-z,测试目录、测试模块、测试类、测试方法/测试函数都按照这个规则来加载测试用例。在有的时候,我们并不希望测试用例按照这样的规则来执行,pytest就可以让我们按......
  • 接手了个项目,被if..else搞懵逼了
    项目会最终沦为屎山,但是作为一个有追求的研发,我们就应当从每个小的ifelse着手,至少让当前这个项目在你维护期间,让其发展成屎山的速度变慢一些,或者能替之前的老前辈还掉一些技术债才是最好的,各位小伙伴你们觉得呢?背景领导:“这个项目,今后就给你维护了啊,仔细点......