重构条件-Replace Nested Conditional with Guard Clauses以卫语句取代嵌套条件式五
创始人
2025-06-01 11:56:02
0

重构条件-Replace Nested Conditional with Guard Clauses以卫语句取代嵌套条件式五

1.以卫语句取代嵌套条件式

1.1.使用场景

函数中的条件逻辑使人难以看清正常的执行路径。使用卫语句表现所有特殊情况

根据我的经验,条件式通常有两种呈现形式。第一种形式是:所有分支都属于正常行为。第二种形式则是:条件式提供的答案中只有一种是正常行为,其他都是不常见的情况。
这两类条件式有不同的用途,这一点应该通过代码表现出来。如果两条分支都是正常行为,就应该使用形如「if…then…」的条件式;如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回。这样的单独检查常常被称为卫语句(guard clauses)

Replace Nested Conditional with Guard Clauses 的精髓就是:给某一条分支以特别的重视。如果使用if-then-else 结构,你对if 分支和else 分支的重视是同等的。 这样的代码结构传递给阅读者的消息就是:各个分支有同样的重要性。

卫语句(guard clauses)就不同了,它告诉阅读者:『这种情况很罕见,如果它真的发生了,请做 一些必要的整理工作,然后退出。

1.2.如何做

  • 对于每个检查,放进一个卫语句。
  • 卫语句要不就从函数中返回,要不就抛出一个异常。
  • 每次将条件检查替换成卫语句后,编译并测试。
  • 如果所有卫语句都导致相同结果,请使用Consolidate Conditional Expressions (240)。

1.3.示例

想像一个薪资系统,其中以特殊规则处理死亡员工、驻外员工、退休员工的薪资。这些情况不常有,但的确偶而会出现。假设我在这个系统中看到下列代码

 double getPayAmount() {double result;if (_isDead) result = deadAmount();else {if (_isSeparated) result = separatedAmount();else {if (_isRetired) result = retiredAmount();else result = normalPayAmount();};}return result;};

在这段代码中,非正常情况的检查掩盖了正常情况的检查,所以我应该使用『卫语句」来取代这些检查,以提高程序清晰度。我可以逐一引入卫语句。让我们从最上面的条件检查动作开始:

 double getPayAmount() {double result;if (_isDead) return deadAmount();if (_isSeparated) result = separatedAmount();else {if (_isRetired) result = retiredAmount();else result = normalPayAmount();};return result;};

然后,继续下去,仍然一次替换一个检查动作:

 double getPayAmount() {double result;if (_isDead) return deadAmount();if (_isSeparated) return separatedAmount();if (_isRetired) result = retiredAmount();else result = normalPayAmount();return result;};

然后是最后一个:

 double getPayAmount() {double result;if (_isDead) return deadAmount();if (_isSeparated) return separatedAmount();if (_isRetired) return retiredAmount();result = normalPayAmount();return result;};

此时,result 变量已经没有价值了,所以我把它删掉

 double getPayAmount() {if (_isDead) return deadAmount();if (_isSeparated) return separatedAmount();if (_isRetired) return retiredAmount();return normalPayAmount();};

将条件反转

  public double getAdjustedCapital() {double result = 0.0;if (_capital > 0.0) {if (_intRate > 0.0 && _duration > 0.0) {result = (_income / _duration) * ADJ_FACTOR;}}return result;}

同样地,我逐一进行替换。不过这次在插入卫语句(guard clauses)时,我需要将相应的条件反过来:

   public double getAdjustedCapital() {double result = 0.0;if (_capital <= 0.0) return result;if (_intRate > 0.0 && _duration > 0.0) {result = (_income / _duration) * ADJ_FACTOR;}return result;}

下一个条件稍微复杂一点,所以我分两步进行逆反。首先加入一个逻辑非操作

  public double getAdjustedCapital() {double result = 0.0;if (_capital <= 0.0) return result;if (!(_intRate > 0.0 && _duration > 0.0)) return result;result = (_income / _duration) * ADJ_FACTOR;return result;}

但是在这样的条件表达式中留下一个逻辑非,会把我的脑袋拧成一团乱麻,所以我把它简化成下面这样

  public double getAdjustedCapital() {double result = 0.0;if (_capital <= 0.0) return result;if (_intRate <= 0.0 || _duration <= 0.0) return result;result = (_income / _duration) * ADJ_FACTOR;return result;}

这时候,我比较喜欢在卫语句内返回一个明确值,因为这样我可以一目了然地看到卫语句返回的失败结果。此外,这种时候我也会考虑使用Replace Magic Number with Symbolic Constant (204)。

  public double getAdjustedCapital() {double result = 0.0;if (_capital <= 0.0) return 0.0;if (_intRate <= 0.0 || _duration <= 0.0) return 0.0;result = (_income / _duration) * ADJ_FACTOR;return result;}

完成替换之后,我同样可以将临时变量移除

  public double getAdjustedCapital() {if (_capital <= 0.0) return 0.0;if (_intRate <= 0.0 || _duration <= 0.0) return 0.0;return (_income / _duration) * ADJ_FACTOR;}

相关内容

热门资讯

原生安卓系统怎样升级,从基础到... 你有没有发现,你的安卓手机用久了,有时候就像老牛拉车一样,慢吞吞的?别急,今天就来给你支个招,让你的...
安卓13系统怎么开发,开发者的... 你有没有听说安卓13系统已经发布了?这可是个大新闻呢!作为一个热衷于手机开发的小伙伴,你是不是也跃跃...
安卓q系统镜像下载,轻松升级体... 你有没有听说安卓Q系统已经发布了?这可是安卓家族里的一大亮点呢!今天,我就要来给你详细介绍一下安卓Q...
安卓系统色彩校正软件,打造个性... 你有没有发现,手机屏幕的色彩有时候会让人感觉不太对劲?有时候,画面看起来有点灰蒙蒙的,有时候又太艳丽...
苹果能否下个安卓系统,开启新篇... 你有没有想过,苹果的iOS系统会不会有一天突然宣布,它要拥抱安卓的大家庭呢?想象iPhone和iPa...
树莓派 装 安卓系统,轻松安装... 你有没有想过,用树莓派装上安卓系统,那会是怎样一番景象呢?想象一个迷你电脑,竟然能运行起我们日常使用...
安卓系统怎么打印小票,安卓系统... 你是不是也遇到了这样的烦恼:手机里存了好多重要的小票,但是想打印出来保存或者报销,却发现安卓系统里的...
安卓10安装系统应用,轻松上手... 你有没有发现,你的安卓手机最近是不是有点儿“慢吞吞”的?别急,别急,今天就来给你支个招——升级安卓1...
美国不提安卓系统华为,迈向自主... 华为与美国:一场关于技术、市场与政策的较量在当今这个数字化的世界里,智能手机已经成为我们生活中不可或...
安卓系统怎么打开ppt,选择文... 你有没有遇到过这种情况:手里拿着安卓手机,突然需要打开一个PPT文件,却怎么也找不到方法?别急,今天...
谷歌退回到安卓系统,探索创新未... 你知道吗?最近科技圈可是炸开了锅,谷歌竟然宣布要退回到安卓系统!这可不是一个简单的决定,背后肯定有着...
安卓系统待机耗电多少,深度解析... 你有没有发现,手机电量总是不经用?尤其是安卓系统,有时候明明没怎么用,电量就“嗖”的一下子就下去了。...
小米主题安卓原生系统,安卓原生... 亲爱的手机控们,你是否曾为手机界面单调乏味而烦恼?想要给手机换换“衣服”,让它焕然一新?那就得聊聊小...
voyov1安卓系统,探索创新... 你有没有发现,最近你的手机是不是变得越来越流畅了?没错,我要说的就是那个让手机焕发青春的Vivo V...
电脑刷安卓tv系统,轻松打造智... 你有没有想过,家里的安卓电视突然变得卡顿,反应迟钝,是不是时候给它来个“大保健”了?没错,今天就要来...
安卓系统即将要收费,未来手机应... 你知道吗?最近有个大消息在科技圈里炸开了锅,那就是安卓系统可能要开始收费了!这可不是开玩笑的,这可是...
雷凌车载安卓系统,智能出行新体... 你有没有发现,现在的汽车越来越智能了?这不,我最近就体验了一把雷凌车载安卓系统的魅力。它就像一个聪明...
怎样拍照好看安卓系统,轻松拍出... 拍照好看,安卓系统也能轻松搞定!在这个看脸的时代,拍照已经成为每个人生活中不可或缺的一部分。无论是记...
安卓车机系统音频,安卓车机系统... 你有没有发现,现在越来越多的汽车都开始搭载智能车机系统了?这不,咱们就来聊聊安卓车机系统在音频方面的...
老苹果手机安卓系统,兼容与创新... 你手里那台老苹果手机,是不是已经陪你走过了不少风风雨雨?现在,它竟然还能装上安卓系统?这可不是天方夜...