程序员修炼之道40-重构
这一章前面几节的内容对于开发不是很有意义,像巧合编程、算法复杂度之类的。所以跳过了他们,直接来到了一个很容易引发激烈讨论的小结——重构
软件构造
这里作者用了一个非常形的比喻描述了软件开发。比起建筑这种,预先构建好蓝图按照步骤一步一步搭建,软件开发更像是园艺,根据每一个时间点植物的状态,对应的调整植物的生长环境,比如土壤、阳光、水之类。
重构是需要一直进行的,而且是低风险小范围的进行。
重构的时机
-
重复
这一点其实是重构最根本的需求,减少重复的代码
-
非正交设计
不知道这里的正交设计是不是指SOLID原则。对于SOLID原则其实我们之前也讨论过,争议最大的就是迪米特法则。我们系统的现状其实也是违反了接口隔离原则,不过这是一个很common的问题,难道我们因为Autowired了CommonDao却没有使用里面的所有方法,就要拆分CommonDao吗,这也是不太合理的。
-
过时的知识
这里突出的是事情和需求变化了,这里和我之前读到的一句话有点类似。重构发生在需求变化的时候。如果需求没有变化,那么就应该让系统以现有的状态一直运行下去。
-
性能
其实这个地方也因人而异,只要不是用户忍无可忍的慢,就不需要重构。而且一般来说提升性能的方式肯定也不是重构,而是修改了逻辑去增速
-
通过了测试
这里强调了添加了新的小功能并且通过了一个新的小测试,就可以整理代码了。这个几乎在我们的系统中不存在,因为我们没有测试
什么时候不应该重构
这个是《重构》这本书上说的,对于你不能够理解透彻的API,哪怕代码非常丑陋,也不要去重构。必须要等到对代码工作原理非常了解了才应该重构。
如何重构
这是一个非常广泛的标题,这里直说一首小诗:
旧的不变
新的创建
一步切换
旧的再见
就是说如果你要替换掉一个老的方法,不要直接动,而是写一个具备同样功能的新的方法,然后一个一个替换掉原有方法的调用,最后删除老的方法。
比如我们的系统中部门是一个树状的层级结构,之前有一个方法是提供root节点,搜索所有的子孙结点。这个方法的做法是遍历,并且将id拼到一个大的string里面,最后在SQL里这个string超长了。所以我写了一个新的方法,通过维护一个子孙关系的视图来查询。之后我测试了新的方法的运行结果和老方法的运行结果一致。最后我替换掉了老方法的所有引用。我不需要测试调用老方法的地方是否受影响,我只需要保证我的新方法和老方法的运行结果一直就可以了