很多时候,作为工程师最主要的工作其实不是写新代码,而是不断的维护和更新现有的代码。一般来说由于早期开发进度的要求,代码质量堪忧。在此分享和总结一下,最近Youtube看的一个Talk – Code Refactoring: Learn Code Smells And Level Up Your Game!。 Refacotring的定义是重构,简单的说就是在没有改变功能的基础上,改进代码。主讲人Sandi Metz是一个非常talented的speaker, 简洁直接重点还有趣,这是我自己听的她的第一个演讲,就看了不下三遍,墙裂建议由翻-墙-条件的前往支持 😃
问题代码![问题代码](https://i-blog.csdnimg.cn/blog_migrate/914ea8e17dc529c78c5591f803f396f2.png)
截图中的ruby代码中sale和expense是作为花费,被Far, foo, bar使用,其中的问题是什么呢?
- 难读 - 代码本身不够直观,total的计算需要去了解date, 也有具体的sum method.
- 难改 - 即使total的计算的微小变化,也期待程序员要改所有usage,出错概率大
- 难测 - 每一个独立的method都需要testing, 虽然逻辑相似
- 难加 - 未来新人大多会复制已有代码,让逻辑更复杂难处理
改进后代码
截图中改进后的代码又有什么样的考虑呢?
- 避免数据组 - 与其每次都要传startDate和endDate, 不如把他们做成一个class, 同时加入一些util method去实现常用任务如得到一周的时间范围。
- 抽象共享逻辑 - Ruby里的module看起来就像是interface, 把所有需要计算总价的东西,共享一个interface. 注意它这里用Dependency injection传入对应的Totable object. 这样做的好处是,一方便扩展到其他类似object, 二本身测试也可以变得很轻便,可以直接mock对应的object,避免了object内部复杂的逻辑,让测试更简单且快速。
具体总结就是学会抽象出可以复用的模块,让这些模块专注于做好一件事情。最后得到的结果会是一批易于测试和维护的代码。另外,在refactoring具体过程中,请一定要确保有测试的存在,这样在你改完的之后,你也有信心最近的更新没有破坏它原有的功能。