一、书籍介绍
书名:《重构 改善既有代码的设计》 作者:[美]Martun Fowler 译者:熊节 出版社:人民邮电出版社
二、背景
深知自己的代码水平,但自己又有一点代码洁癖,看不惯的代码,自己重构后自觉美感还是欠佳,还是要多看书。本博文希望自己看完一章就写点感悟,不能囫囵吞枣,借此提高自己,也让我可以愉快撸码。
三、感受
2018.04.03
今天试着重构公司的框架,通过接口+抽象类抽出顶层结构,使得其子类减少了至少15行代码,因为子类多,整个项目明显精简很多。接口也统一了使用http和mqtt两种协议,还是可以的。
四、正文
第一章 重构,第一个案例
本章重构一个计算根据顾客租用影片类型和租期计算费用的程序,期间用到了Extract Method(额外方法)、Move Method(移动方法)、Replace Conditional With Polymorphism(以多态替代条件表达式)、Self Encapsulate Field(自封装字段)、Replace Type Code With State/Strategy(以State/Strategy模式取代类别码)等重构方法。
这一章的作用在于Quick Start,所以我们可以不用过多关注于重构方法。为什么要重构?是因为系统代码设计的不合理,日渐臃肿,变得难以拓展,我们维护起来也特别痛苦。如何学会重构?我觉得是要真正理解面向对象思想,这一点我觉得我还是没能做到。作者就是能理解各个类的职责,每个类该拥有什么方法,能做出这样准确的判断,才能做好重构,才是真正面向对象。除此之外设计模式也很重要,GOF的经典之作,等看完了这本书再去拜读。
第二章 重构原则
本章讲述了什么是重构,重构的好处,什么时候重构,重构与设计和性能。
重构既可以是对现有代码结构上的优化也可以指一系列重构的手法。
重构的好处不言而喻。重构使项目代码更容易理解,写出使机器理解的代码,即使笨的人也可以,但是要写出能让人理解的代码,确是不容易的;重构能帮助你更快找到bug,重构使代码组件化,各个组件功能高内聚,这使得bug定位相对简单;重构加快编码速度,j结构良好的代码拓展起来容易。
那我们什么时候应该重构呢?三次原则,即相同的代码重写超过3次就该考虑重构了。重构不是在特点的时间段执行的,它应该贯穿整个项目的生命周期,随时随地进行,当然如果到了项目最后阶段,就不用重构了。
重构前应该进行设计,我觉得这不仅对于重构,我们写任何代码,都要提前设计,也就是想好再去写。重构应不应该兼顾性能呢?重构只是代码结构的优化,性能优化则是另外的课题了。有时候性能高的代码结构并不好,维护起来相对困难,而如果这些代码执行概率低的话,这样就显得弊大于利。我的观点是,执行次数多,性能优化大于结构优化;执行次数少,结构优化大于性能优化,而往往结构优化的代码,性能并不会很差,这使得我们维护起来容易。
第三章 代码的坏味道
讲的是22种代码中出现的情况,预示着可能需要重构。
第四章 构筑测试框架
测试有助于提高编程速度,通常我们的工作大部分都在完善程序的健壮性。
编写单元测试的一般性步骤(前提已经导入junit库):
1)创建类名为 目标类名+Test 并且继承于TestCase;
2)重写setUp方法:为测试前做准备工作;重写tearDown方法:为测试后做善后工作(比如关闭连接);
3)编写以test为前缀且返回值为空的测试方法,善用assertEquals方法;
4)将单元测试类加入TestSuite对象并在main方法调用TestRunner.run方法进行测试(可同时测试多个类),得到的常规单元测试类如下:
public class HelloWorldTest extends TestCase{ Log log = LogFactory.getLog( HelloWorldTest.class ); @Override protected void setUp() throws Exception { log.info( "Setup" ); super.setUp(); } @Override protected void tearDown() throws Exception { log.info( "tearDown" ); super.tearDown(); } public void testHello() { assertEquals( "hello", "hello" ); } public static void main(String[] args) { TestRunner.run( suite() ); } private static TestSuite suite() { TestSuite suite = new TestSuite(); suite.addTest( new TestSuite(HelloWorldTest.class) ); return suite; } }
在测试中注意边界测试。
第5章 重构列表