⼀本值得反复学习的好书——《重构》读后感
⽂章⽬录
读书总结
总计花了⼤概两周,每天上下班各有半⼩时左右的时间,读完了《重构——改善既有代码的设计(第⼆版)》,获益良多,虽然从开始学习编程起就⼀直很注意代码的可读性和代码结构的维护,但是毕竟经验尚浅,⽆论是⼴度还是深度都远远不够。
读书过程中不仅有很多平时只是浑浑沌沌感受到的把代码写好的原则被作者轻⽽易举地点透了,同样还有很多以前⾃以为是认为能把代码写好实际上却增加了代码复杂度的错误被发现了。
书籍结构
值得看的好书书籍主要分为五⼤部分:
1. 开篇是⼀个重构的具体案例,展⽰了对⼀段代码的完整重构过程;
2. 接下来是对重构⼏个⽅⾯的解释,包括对重构的定义、重构的⽬的和重构的时机等;
3. 第三个⼤部分是代码的坏味道,直⽩地说,就是代码⾥需要进⾏重构的具体表现,我认为这是整部书中最重要的部分;
4. 测试的重要性——重构的基础是测试,要想保证重构不使程序被破坏,测试环境是必须的;
5. 最后⼀个⼤部分是具体的重构⼿法,这⾥展⽰了⼤量的重构⼿法,每⼀种⼿法都有⽐较具体的使⽤场景,很多⼿法也会使⽤到其他的
重构⼿法,这也是整部书中占篇幅最⼤的部分。
我整理了⼀个思维导图,帮助理解整部书的结构和为以后复习作准备:
⼀部形成了完整⽅法论的书籍
这是⼀本形成了完整的重构⽅法论的书籍,从什么是重构(What)到为什么要进⾏重构(Why),再到何时进⾏重构(When),以及**如何进⾏重构(How)**都⼀⼀进⾏了详细的展⽰,内容相当充实和丰富,并且结构⾮常合理,⽆论是提纲契领的思想还是具体的操作⼿法都流畅地进⾏了展现。
⼀部值得反复学习和实践的书籍
从厚度上来说,这本书加上序⾔和书末的索引也就不到四百五⼗页,但内容却⼗分充实,并不像很多书籍⼀样注⽔严重,接近六⼗种具体的重构⼿法、⼆⼗⼏种代码的“坏味道”、重构原则中的What、Why、When等,都不是只把书籍阅读⼀遍就可以完全吸收的,值得细细学习体会并在具体⼯作中进⾏实践,以提⾼代码质量。
⼀部阅读体验⾮常与众不同的书籍
“代码的坏味道”这个篇章紧接在重构的原则这个篇章之后。
虽然作者已经尽⼒把第⼀个案例选得简短,但是连续四⼗页的重构还是读起来有些累,⽽“重构的原则”这个篇章⼜显得太虚了些,终于到了“代码的坏味道”这个篇章,这部书就开始展现出与其他书籍阅读体验⾮常不同的特点,让我精神⼀振。
这个篇章⾥提出了⼆⼗四种“坏味道”,每⼀种“坏味道”⾥除了对“坏味道”本⾝的描述之外,还对具体的解决思路和解决⽅法进⾏了提炼。前⾯有提到,书中提供了近六⼗种具体的重构⼿法,在每⼀种坏味道的解决⽅法中,都有具体的重构⼿法的引⽤,⽽具体的重构⼿法也会经常对其他的重构⼿法进⾏引⽤——这仿佛是作者制作了⼀个解决问题的栈,形成了下⾯这样的阅读流程:
引⽤重构⼿法
引⽤重构⼿法
引⽤重构⼿法
解决问题
这种“类栈”的阅读让我想起了以前玩的分⽀选择互动⼩说,但放在技术书籍⾥可以说是相当少见了。
代码的坏味道
我在前⾯说,这是我认为整部书中最重要的⼀个部分,重构的原则部分显得太过虚了些,⽽后⾯具体的重构操作⼜跟具体的语⾔结合地紧密了些(虽然作者尽⼒在减少这种语⾔相关的差异),⽽这⼀部分不仅描述了坏代码的具体场景,还给出了解决⽅案,具有极强的实操性。
极其常见的⼏种坏味道
这⼆⼗四种坏味道中,有⼏种是极其常见的:
1. 神秘命名——取名是程序员的天敌,但取个好名字⼜极其重要,这也是稍有⾃觉的程序员都会注意的地⽅,可惜的是,取名实在是太
难了(作者给这么多重构⼿法和坏味道都⼀⼀取了名字真是⾟苦了);
2. 重复代码——⼤家都戏称编程只需要三个键:Ctrl、V、C,由此也可知重复代码的常见性,遗憾的是这却是代码中最刺⿐的坏味道之
⼀,恐怕也是代码中最屎⼭的最⼤来源之⼀;
3. 过长函数——⼜是⼀个极其常见的坏味道,“屎⼭”的最重要组成,没有之⼀,我曾经在项⽬中见过长达两千⾏的超长函数,结尾处
⼤括号}套了⼆⼗⼏层,看得我头⽪发⿇;作者在这⼀种坏味道中提出了⼀个有意思的观点:就算只有⼀⾏代码,如果它需要以注释来说明,那也值得将它提炼到独⽴函数中去;
4. 全局数据——同样是⼀个被滥⽤的代码组织⽅式,在带GC的语⾔中⼜显得尤其恶⼼,导致各种“伪内存泄漏”的元凶;
5. 基本类型偏执——关于这⼀种坏味道,其实我在C#中见得很少,但在C++项⽬中见得尤其多,⼤概是没能成功从“带class的C语
⾔”转换到“⾯向对象的C++”造成的吧;
6. 过⼤的类——这往往跟过长函数同时出现,都是屎⼭上最璀璨的明珠;
带给我⼀些新思考的⼏种坏味道
有⼀些坏味道是我以前偶尔瞥见但没上⼼的,这次在书中看到,却给了我⼀些新的思考:
1. 可变数据——如果⼀个变量多次被赋值,并且在不同的时候保存了多个不同的东西,那么它必然可以使⽤⼏个范围更⼩的临时变量进
⾏替代,多次赋值是⾮常危险的,因为你需要⼩⼼地去处理每⼀次变化,但如果把这个数据变成只进⾏⼀次赋值,那么它的使⽤就变得⾮常安全了。
2. 循环语句——给我思考的其实不是这个坏味道本⾝,⽽是作者提出来的解决办法:以管道取代循环;我以前⼀直固执地想要在⼀次循环
中解决所有问题,并且天真的认为少循环⼀次可以节省⼀些性能,虽然确实性能要好⼀些,但是多数情况下,多⼀次循环并不会造成致命的性能问题;相反,如果多⼀次循环,可以把具体的操作分隔开来,可以更清楚地展现出处理问题的思路——即使真的造成了性能问题,后期再进⾏改造也会更加容易。
3. 纯数据类——这⼀种味道在很多静态语⾔中可能并不是“坏味道”,⽽是⽤于某些具体模块的数据其类,⽐如masterdata的序列化、
通信的数据序列化。但是我赞同作者的⼀点是,尽可能不要把这些数据直接使⽤,⽽还是要进⾏⼀层封装,如果直接使⽤了这些数据,说明结构肯定是存在问题的——处理数据的类和具体的数据之间⼀定要分隔开来,并且原数据要尽可能不发⽣改变。
结语
计划2021年再读⼀遍,值得再次学习。