一、KISS
1、概念
这个是目测最简单的原则了,KISS原则:Keep It Simple And Stupid(Short、Straightforward)。不管是小括号里的哪种解释,最终表达的含义都是尽量保持简单。代码足够简单,也就意味着很容易读懂,bug 比较难隐藏。即便出现 bug,修复起来也比较简单。
2、怎么才算“简单”
完成同一个需求所用的代码行数越少就越简单了吗?我觉得未必!我觉得简单二字应该是代码行数越少而且易读才算简单。举个最傻X的例子,你TM用二进制给我写一堆代码完成一个需求,假设这个需求你这个代码行数很少,但是谁看的懂?这简单吗…?看下面的例子,三段代码,每段都是实现ip校验规则的。
// 第一种实现方式: 使用正则表达式
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原则?也就是哪种最简单?第一种显然代码行数最少,但是不易读。第三种性能肯定最高,但是是自己写的容易出问题,我觉得如果ip校验没影响到性能的话,那么这么做就是过度优化。第二种就很完美,采取靠谱的库来完成需求,代码量也不大且易读。这就叫KISS原则。也并非复杂逻辑就不符合KISS了,比如一些算法,KMP、动态规划、树等,这些本身就很复杂,所以我觉得没必要谈KISS。
3、如何写出满足KISS原则的代码
- 尽量别用同事可能看不懂的东西写代码(并不是说高端技术,而是比如正则、一长串的三目表达式等)
- 别重复造轮子,善于使用已经有的工具类库
- 别过度优化
二、YAGNI
YNGNI:You Ain’t Gonna Need It. 也就是说你不会需要它。其实也是再说不要过度设计。举个最傻X的例子:我这项目Mysql就够了目前不用Redis,那就别把Redis的代码都写了,没必要这种过度的设计。你不需要它。
再比如:我们依赖的jar包,比如maven的gav坐标,你不需要xxx.jar,就别把它的gav写进来,这种的做法其实也是违背YAGNI原则的。
三、总结
KISS说的是如何做的简单的问题,YAGNI说的是要不要做的问题,还是有区别的。