为啥你写的代码老有大串的if/else?
摘要:控制语句,到底何错之有呢?
本文分享自华为云社区《业务代码如何才能不再写出大串的if/else?》,作者: JavaEdge 。
控制结构?没错!你最爱的 if、for都是一类坏味道,没想到吧?自己竟然每天都沉浸在写坏味道的体验中。
控制语句,到底何错之有呢?
嵌套代码
CR 如下分发我刚写完的一篇博客的案例:

逻辑很简单,但有多层缩进,for 循环一层,里面有俩 if ,又多加两层。若逻辑再复杂点,缩进岂不是像啤酒肚一般越来越大?
为啥代码会写成这鬼样子呢?
因为你在写流水账,如机器人般地按需求一步步翻译成代码。
代码逻辑肯定没错,但功能实现后,未重新整理代码。
现在就得消除缩进。
从for循环入手,通常for循环处理集合,而循环里处理的是该集合中的元素。所以,可将循环中的内容提取成方法,只处理一个元素:

这就是一次拆分,分解出来事务 issueArticle 每次只处理一个元素。这就优化了缩进问题:
- issueArticles 只有一层缩进,这才是正常方法应有的样子。
- 但 issueArticle 还残留多层缩进,待继续优化。
if 和 else
issueArticle 里,造成缩进的原因是 if 语句。if 缩进很多时候都是在检查某先决条件,条件通过时,才能执行后续代码。
这样的代码可使用卫语句(guard clause),即设置单独检查条件,不满足该检查条件时,方法立刻返回。
以卫语句取代嵌套的条件表达式(Replace Nested Conditional with Guard Clauses)。
重构后的 issueArticle 函数:

如今这就只剩一层缩进,代码复杂度大大降低,可读性和可维护性也大大增强。
禁用else
大多数人印象中,if 和 else 几乎比翼齐飞。
else 可以不写吗?
可以!
根据文章信息进行收费:

不用 else,简单方式就是让每个逻辑提前返回,类似卫语句:

业务简单的代码,这重构还很轻松,但对复杂代码,就得上多态了。
嵌套、else 语句,都是坏味道,本质上都在追求简单,因为一段代码的分支过多,其复杂度就会大幅度增加。
衡量代码复杂度常用的标准,圈复杂度(Cyclomatic complexity,CC),CC越高,代码越复杂,理解和维护的成本越高。
在CC判定中,循环和选择语句占主要地位。CC可使用工具检查,如Checkstyle,可限制最大的圈复杂度,当圈复杂度大于设定阈值,就报错。
重复 Switch

实际支付的价格会根据用户在系统中的用户级别有所差异,级别越高,折扣越高。
两个函数里出现了类似的代码,其中最类似部分就是 switch,都据用户级别判断。
这并非仅有的根据用户级别进行判断的代码,各种需区分用户级别场景都有类似代码,而这也是一种典型的坏味道:重复switch(Repeated Switch),通常都是因为缺少一个模型。
解决方案:以多态取代条件表达式(Relace Conditional with Polymorphism)。
引入 UserLevel 模型,消除 switch:

前面代码即可去掉 switch:

switch 其实就是一堆“ if…else” 的简化写法,二者等价,所以,这个重构手法,以多态取代的是条件表达式,而不仅是取代 switch。
为啥你写的代码老有大串的if/else?的更多相关文章
- 朱晔的互联网架构实践心得S2E2:写业务代码最容易掉的10种坑
		我承认,本文的标题有一点标题党,特别是写业务代码,大家因为没有足够重视一些细节最容易调的坑(侧重Java,当然,本文说的这些点很多是不限制于语言的). 1.客户端的使用 我们在使用Redis.Elas ... 
- 详解DDD:如何避免写流水账代码?
		在日常工作中我观察到,面对老系统重构和迁移场景,有大量代码属于流水账代码,通常能看到开发在对外的API接口里直接写业务逻辑代码,或者在一个服务里大量的堆接口,导致业务逻辑实际无法收敛,接口复用性比较差 ... 
- 写Java代码的一些小技巧
		写Java代码有三年多了,遇到过很多坑,也有一些小小的心得.特地分享出来供各位学习交流.这些技巧主要涉及谷歌Guava工具类的使用.Java 8新特性的使用.DSL风格开发.代码封装等技巧. 一.nu ... 
- 使用Vim写LaTeX代码(Vim+Vimtex+Skim)
		最近在写博客的时候发现对数学公式的支持并不好,于是就想寻找一个解决方案.我本身是一个爱折腾的人,有时尽管有现成的解决方案我有事也不愿意去用.于是多方查找资料,想寻求一个自定义的解决方案,最终把自己的目 ... 
- .net学习之Session、Cookie、手写Ajax代码以及请求流程
		1.IIS 7 以上版本集成了两种模式,一种是经典模式,一种是集成模式(直接将asp.net框架集成到IIS中) 2.浏览器和服务器端通过什么技术来实现的?Socket(套接字),通信的语法是HTTP ... 
- jQuery之父:每天都写点代码
		去年秋天,我的“兼职编程项目”遇到了一些问题:要不是从 Khan Academy 的项目里挪出时间来的话,我根本没办法将不理想的进度弥补上. 这些项目遇到了一些严重的问题.之前的工作我主要是在周末,有 ... 
- Wix#可以直接写C#代码来生成Wix的MSI安装文
		博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:Wix#可以直接写C#代码来生成Wix的MSI安装文. 
- 关于 OnCloseQuery: 顺序、不能关机等(所有的windows的广播消息都是逐窗口传递的)——如果一个窗体的OnCloseQuery事件中如果写了代码那么WM_QUERYENDSESSION消息就传不过去了msg.result会返回0,关机事件也就停止了
		系统关闭窗体的事件顺序为: OnCloseQuery ----> OnClose ----> OnDestroy 下面的代码说明问题: unit Unit3; interface uses ... 
- Lombok :  让你写 Java代码像C#一样爽
		前言 我曾经是一名 .Net 开发,如今的我是一名 Java 开发者.在我享受着 Java 成熟的生态时,我常常怀念 c# 简洁的语法:自动属性.类型推断.自动初始化器 .... 鱼,我所欲也,熊掌亦 ... 
- 不写一行代码,利用常用工具和软件批量下载URL资源
		有时候会遇到这种情况:想从某个网站下载一批东西,目标URL是比较规整的,而且结构都一样(仅某些字段不同).但又懒得开IDE专门写个脚本去弄,今天就和大家分享一下,如何利用手边常用的软件和工具,不用写一 ... 
随机推荐
- 导出所有容器id号
			#!/bin/bash a=`docker ps|awk 'NR>1{print $1}'` FORMAT="%-12s\t,\t%-12s\t,\t%-12s\n" pri ... 
- C#工作流——elsa-workflows
			介绍 Elsa Workflows 是一个功能强大且灵活的执行引擎,封装为一组开源 .NET 库,旨在为 .NET 应用程序注入工作流功能. 借助 Elsa,开发人员可以将逻辑直接编织到他们的系统中, ... 
- PVE 下虚拟机 Ubuntu 无法进入恢复模式的解决方案——提取原有系统文件
			问题说明 某天重启虚拟机 Ubuntu,发现虚拟机只有容器IP,桥接的接口在虚拟机显示状态为 DOWN: 想重启进入恢复模式,却发现恢复模式一直花屏,无法使用: 没有办法了,只能想办法提取原有系统内原 ... 
- 实验代码Javaweb
			package test; import java.sql.*; import java.util.regex.Pattern; public class Data { //getter and se ... 
- 231106-jmeter随笔
			1. 获取接口的执行时间 String ctime = prev.getTime().toString();2. String转int int c = Integer.parseInt(ctime); ... 
- Springboot+shiro,完整教程,带你学会shiro
			您的第一个 Apache Shiro 应用程序 引入依赖: <?xml version="1.0" encoding="UTF-8"?> <p ... 
- 高效的 Json 解析框架 kotlinx.serialization
			一.引出问题 你是否有在使用 Gson 序列化对象时,见到如下异常: Abstract classes can't be instantiated! Register an InstanceCreat ... 
- [USACO2007FEBS] Cow Party S
			题目描述 寒假到了,\(n\) 头牛都要去参加一场在编号为 \(x\) 的牛的农场举行的派对,农场之间有 \(m\) 条有向路,每条路都有一定的长度. 每头牛参加完派对后都必须回家,无论是去参加派对还 ... 
- MybatisPlus查询时过滤不需要的字段~
			解释一下:乍一看标题可能有点懵~,其实就是想查询的时候过滤掉某些字段 例如: select name,email,password from user; --改为-> select name,e ... 
- Java并发(二十)----synchronized原理进阶
			1.小故事 故事角色 老王 - JVM 小南 - 线程 小女 - 线程 房间 - 对象 房间门上 - 防盗锁 - Monitor-重量级锁 房间门上 - 小南书包 - 轻量级锁 房间门上 - 刻上小南 ... 
