KISS 定义
kiss 原则的英文描述又几个版本,计较下边的这几个
keep it simple and stupid.
keep it short and simple
keep it simple and straightforward
不过仔细看你会发现,他们表达的意思其实差不多,尽量保持简单。 它是一个万金油的设计原则,可以在很多场景中,它不仅仅经常用来指导软件开发,还经常指导更广泛的设计,比如冰箱,建筑,Iphone 手机的设计等等。
我们指导可读性和可维护性,是衡量代码质量的非常重要的两个标准。而kiss 原则是保持代码可读性和可维护性的重要手段。 代码足够简单,也就意味着很容易读懂,bug 比较难隐藏。即便出现bug ,修复起来也比较简单。
不过这天原则告诉我们要保持“Simple and stupid”,但是并没有讲过,什么代码才是Simple and stupid ,更没有明确的方法论,来指导如何开发Simple and stupid 的代码。 所以看起来非常简单,但不能落地。 这有点像我们的心灵鸡汤,哦,我们这里应该叫技术鸡汤。
代码行数越少就越简单吗?
// 第一种实现方式: 使用正则表达式 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() 函数是影响系统性能的 瓶颈代码,否则,这样优化的投入产出比并不高,增加了代码实现的难度、牺牲了代码的可 读性,性能上的提升却并不明显。
如何写出满足KISS 原则的代码?
不要使用同事可能不懂得技术来实现代码,比如前面例子中得正则表达式。还有一些编程语言中得过于高级的语法扽给。
不要重复造轮子,要善于使用已经有得工具类库,经验证明,自己去实现这些类库,出现bug 的概率会 更高,维护的成本也更高。 (但是你没有提高)
不要过度优化,不要是公用一些奇技淫巧,比如位运算代替算数运算,复杂的条件代替if -else
实施上,代码是否足够简单,式一个主观的评判,同样的而代码,有人觉得简单有人觉得不够简单。所以评判代码是否简单,还有一个有点的方法,那就是code review 。如果在code review 的时候,同事对你的代码有很多疑问,那就说明,你的代码可能不够简单。需要优化。
这力我还要多说两句,我们在开发的时候,一定不要过度设计,不要觉得简单的东西没有技术含量,实际上越是呢个简单的方法解决复杂的问题,越能体现一个人的能力。
YAGNI 原则,
不要设计当前用不到的功能,不要去编写用不到的代码, 实际上这条代码的原则是不要多读设计。
比如,我们的系统暂时只用 Redis 存储配置信息,以后可能会用到 ZooKeeper。根据 YAGNI 原则,在未用到 ZooKeeper 之前,我们没必要提前编写这部分代码。当然,这并 不是说我们就不需要考虑代码的扩展性。我们还是要预留好扩展点,等到需要的时候,再去 实现 ZooKeeper 存储配置信息这部分。
在比如我们不要在项目中引入不需要的依赖开发包。 我们呢发现,有些同事为了避免library 包的确实频繁的修改和maven gradle 的配置,提前往项目中引入大量的常用的library 包,实际上也是违背了yangni 原则。
KISS 原则讲的是如何做,YAGNI 原则是讲的要不要做。
标签:return,原则,实现,代码,ipUnitIntValue,KISS,false,设计模式 From: https://www.cnblogs.com/dousil/p/18039312