两个简单的基本设计原则 KISS原则和YAGNI原则
KISS原则比较简单,但是存在几个版本比如
Keep It Simple and Stupid
Keep It Short and Simple
Keep It Simple and Straightforward
其表达的意思为尽量保证简单
Kiss原则是一个万金油的设计原则,其核心是为了保证代码的可读性和可维护性,代码足够简单,就容易读懂,bug难以隐藏
但是如何才是所谓的简单的代码呢?
难道是代码行数越少,就意味着简单吗?
// 第一种实现方式: 使用正则表达式
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; } |
在上面代码中,分别用三种实现方式,去实现检查输入的字符串ipAddress是否是合法的IP地址
一个合法的IP地址由四个数字组成,并且通过 “.”来分割,那么哪种实现方式是符合KISS的呢?
第一种,使用了正则表达式,虽然最少,但是并不符合KISS原则,因为正则表达式其并不简单,如果对于不懂得正则表达式的同事来说,是不友好的
第二种,使用了StringUtils类,Integer类提供的一些现成的工具函数,来处理IP地址字符串,虽然是利用了其他类,但是利用现成的不容易出现bug
第三种,自己编写,写出来有难度,而且思维逻辑并不清晰,所以,第二种更符合KISS原则
代码逻辑复杂就违背KISS原则吗?
虽然有些时候,写出来的代码难以阅读,实现难度大,可读性低,但是是否符合KISS原则,是需要判断的
比如,一个KMP算法的实现很困难,但是我们需要做的产品主要功能就是为了字符串的查找,那么使用KMP去解决,并不违反KISS原则,对于复杂的问题,使用复杂的方法区解决,是可行的
如何写出满足KISS原则的代码呢?
1.不要使用同时不懂的技术来实现代码,比如前面的正则表达式
2.不要重复造轮子,对于可以直接利用的工具类库,去使用工具类更好
3.不要过度优化,不能过度使用某些奇技淫巧(比如位运算,复杂时候的if-else),降低可读性
而YAGNI原则,则是针对的是否过度设计的产生的
全称为 You Ain’t Gonna Need It,不会需要它
也就是在软件设计中,不要设计当前用不到的功能,不去编写当前用不到的代码,不要做过度设计
也就是我们现阶段只有MySQL做数据,可能以后加上Redis,就不要先去编写Redis相关的代码,等到需要的时候,再去实现Redis相关的代码
再比如,我们使用Maven或者Gradle来管理依赖的类库的时候,可能为了避免包的缺失而提前导入大量的包,这是违背YAGNI原则的