我们先一起看一个例子。下面这三段代码可以实现同样一个功能:检查输入的字符串 ipAddress 是否是合法的 IP 地址

一个合法的 IP 地址由四个数字组成,并且通过“.”来进行分割。每组数字的取值范围是 0~255。第一组数字比较特殊,不允许为 0。对比这三段代码,你觉得哪一段代码最符合 KISS 原则呢?如果让你来实现这个功能,你会选择用哪种实现方法呢?你可以先自己思考一下,然后再看我下面的讲解。


// 第一种实现方式: 使用正则表达式
public boolean isValidIpAddressV1(String ipAddress) {if (StringUtils.isBlank(ipAddress)) return false;String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";return ipAddress.matches(regex);
}// 第二种实现方式: 使用现成的工具类
public boolean isValidIpAddressV2(String ipAddress) {if (StringUtils.isBlank(ipAddress)) return false;String[] ipUnits = StringUtils.split(ipAddress, '.');if (ipUnits.length != 4) {return false;}for (int i = 0; i < 4; ++i) {int ipUnitIntValue;try {ipUnitIntValue = Integer.parseInt(ipUnits[i]);} catch (NumberFormatException e) {return false;}if (ipUnitIntValue < 0 || ipUnitIntValue > 255) {return false;}if (i == 0 && ipUnitIntValue == 0) {return false;}}return true;
}// 第三种实现方式: 不使用任何工具类
public boolean isValidIpAddressV3(String ipAddress) {char[] ipChars = ipAddress.toCharArray();int length = ipChars.length;int ipUnitIntValue = -1;boolean isFirstUnit = true;int unitsCount = 0;for (int i = 0; i < length; ++i) {char c = ipChars[i];if (c == '.') {if (ipUnitIntValue < 0 || ipUnitIntValue > 255) return false;if (isFirstUnit && ipUnitIntValue == 0) return false;if (isFirstUnit) isFirstUnit = false;ipUnitIntValue = -1;unitsCount++;continue;}if (c < '0' || c > '9') {return false;}if (ipUnitIntValue == -1) ipUnitIntValue = 0;ipUnitIntValue = ipUnitIntValue * 10 + (c - '0');}if (ipUnitIntValue < 0 || ipUnitIntValue > 255) return false;if (unitsCount != 3) return false;return true;
}

第一种实现方式利用的是正则表达式,只用三行代码就把这个问题搞定了。它的代码行数最少,那是不是就最符合 KISS 原则呢?答案是否定的。虽然代码行数最少,看似最简单,实际上却很复杂。这正是因为它使用了正则表达式。

一方面,正则表达式本身是比较复杂的,写出完全没有 bug 的正则表达本身就比较有挑战;另一方面,并不是每个程序员都精通正则表达式。对于不怎么懂正则表达式的同事来说,看懂并且维护这段正则表达式是比较困难的。这种实现方式会导致代码的可读性和可维护性变差,所以,从 KISS 原则的设计初衷上来讲,这种实现方式并不符合 KISS 原则。

讲完了第一种实现方式,我们再来看下其他两种实现方式。

第二种实现方式使用了 StringUtils 类、Integer 类提供的一些现成的工具函数,来处理 IP 地址字符串。

第三种实现方式,不使用任何工具函数,而是通过逐一处理 IP 地址中的字符,来判断是否合法。从代码行数上来说,这两种方式差不多。但是,第三种要比第二种更加有难度,更容易写出 bug。从可读性上来说,第二种实现方式的代码逻辑更清晰、更好理解。所以,在这两种实现方式中,第二种实现方式更加“简单”,更加符合 KISS 原则。

不过,你可能会说,第三种实现方式虽然实现起来稍微有点复杂,但性能要比第二种实现方式高一些啊。从性能的角度来说,选择第三种实现方式是不是更好些呢?在回答这个问题之前,我先解释一下,为什么说第三种实现方式性能会更高一些。一般来说,工具类的功能都比较通用和全面,所以,在代码实现上,需要考虑和处理更多的细节,执行效率就会有所影响。而第三种实现方式,完全是自己操作底层字符,只针对 IP 地址这一种格式的数据输入来做处理,没有太多多余的函数调用和其他不必要的处理逻辑,所以,在执行效率上,这种类似定制化的处理代码方式肯定比通用的工具类要高些。

不过,尽管第三种实现方式性能更高些,但我还是更倾向于选择第二种实现方法。那是因为第三种实现方式实际上是一种过度优化。除非 isValidIpAddress() 函数是影响系统性能的瓶颈代码,否则,这样优化的投入产出比并不高,增加了代码实现的难度、牺牲了代码的可读性,性能上的提升却并不明显。

总结

  • 代码行数少并不意味着简单

代码行数越少就越“简单”吗?相关推荐

  1. eclipse代码量统计插件_Android Studio 代码行数统计插件Statistic的简单使用

    在项目开发过程中,有时候需要统计代码行数(比如组长想关心一下你的代码量,或者要申请软件著作权时),需要统计的文件类型主要是 .java..xml..kt等,已经有人开发好相关插件了,如果你是用Andr ...

  2. 在项目开发中统计代码行数的6种方式

    文章目录 一.使用find和wc命令统计代码行数 进行参数的过滤筛选 命令参数简要说明 二.PowerShell工具统计代码行数 条件过滤 输出所有文件的行数 PowerShell相关命令的简要说明 ...

  3. 程序员的代码行数真的越少越好吗?

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方留言必回,有问必答! 每天 08:00 更新文章,每天进步一点点... 代码行 ...

  4. 程序员的代码行数越少越好?

    代码行数越少越好?读懂别人的代码很困难?如何编写出"完美"的代码?每天要坚持8小时编程?......拜托,这些编程误区程序员应该尽早知道! 作者 | Ryland Goldstei ...

  5. 实际返回的行数超出请求的行数_代码行数越少越好?

    代码行数越少越好?读懂别人的代码很困难?如何编写出"完美"的代码?每天要坚持8小时编程?......拜托,这些编程误区程序员应该尽早知道! 以下为译文: 作为开发人员,你会听到许多 ...

  6. python计算营业额代码_python计算营业额的代码_python 统计代码行数简单实例

    python 统计代码行数简单实例 送测的时候,发现需要统计代码行数 于是写了个小程序统计自己的代码的行数. #calclate_code_lines.py import os def afileli ...

  7. java 方法数统计_利用Java简单实现一个代码行数统计器方法实例

    前言 哈喽,我是小黑, 最近学了java的输入输出流后一直心痒痒,总想找一点事情来做,所以用java代码来实现了一下统计代码的所有行数,看一下我上大学以来到底打了多少行. 先附上实现代码吧! pack ...

  8. 【Python】72行实现代码行数统计,简单实用~

    0. 前言 最近突然想知道自己总共写了多少行代码,于是做了这样一个小工具-- 1. 准备工作 先考虑一下希望得到的效果: Language(语言) Lines(代码行数) Size(代码文件总大小) ...

  9. 奇葩公司按代码行数算工资,员工一个月提成2.6万遭开除

    Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 来源丨java那些事 之前,有这么一个帖子吸引了很多 ...

最新文章

  1. 会议重点介绍芯片设计中的人工智能
  2. 【Android 应用开发】Android屏幕适配解析 - 详解像素,设备独立像素,归一化密度,精确密度及各种资源对应的尺寸密度分辨率适配问题
  3. python php multiprocessing,Python多进程并发(multiprocessing)用法实例详解
  4. (13)VHDL时序逻辑
  5. 本地提交到yarn_Yarn运行Flink作业 0449
  6. C#/WPF学习笔记:起始
  7. IntelliJ-IDEA-Debug技巧
  8. XcodeGhost:墙、感染、信任和欺骗
  9. ET框架---UnityWebRequestAsync学习笔记
  10. 企业公众号如何申请开通模板消息功能?
  11. 苹果开发者关联封号扫盲贴
  12. 268. 丢失的数字【我亦无他唯手熟尔】
  13. app开发快速理解——webview网页显示
  14. 关于linux校准时间
  15. Android应用内社区SDK技术架构浅析
  16. 微信H5分享朋友圈踩坑
  17. 从来不是别人的不幸和痛苦
  18. 【毕业设计】深度学习驾驶行为状态检测系统(疲劳 抽烟 喝水 玩手机) - opencv python
  19. 用大数据思考用户体验 纪学锋谈《江湖》特色
  20. PV操作与前趋图题型

热门文章

  1. 常见的SAS接口类型、接口连接器外观详细解读
  2. 安全地更改grub2屏幕分辨率
  3. 阿里云服务器Ubuntu16.04安装Anaconda(python3.6)和本地远程连接jupyter
  4. python面试题及答案 2019-这些2019年常考的Python面试题你都能答上来吗?
  5. shell 写文件写入内容
  6. oracle替换指定字符串字符_实例:替换方框内字符串内容
  7. python匹配部分字符串_python – 即使只是部分匹配字符串,如何匹配字符串?
  8. python表单防重复提交_传统方式提交表单,防止重复提交问题?
  9. python 命令模式_python设计模式(十六):命令模式-阿里云开发者社区
  10. 邹城的关于机器人教育_【喜报】我校机器人队问鼎全国大学生机器人大赛冠军!...