《重构》读后感(第三章)

第三章:在何处重构。

决定何时重构以及何时停止重构与知道重构机制如何运转一样重要。

1、神秘代码:整洁代码最重要的一环就是好的名字。命名是编程中最难的两件事之一(扩展阅读:另一件是缓存失效)。
2、重复代码:注意是否有细微差异,以及其调用者等,这决定了我们要怎么去处理它。
3、过长函数:函数越长,越难理解。让小函数易于理解的关键还是在于良好的命名,这样我们只看函数名而不用看整段代码就知道这个函数在做什么,随意起的名字只会让我们浪费更多时间。作者说:每当感觉需要以注释来说明点什么的时候,我们就可以把要说明的东西写进一个独立的函数中,然后以其用途来命名(不要在意其函数名长度)。不过我们自己也应该看情况决定是否需要这么做(最后一条有说明)。
4、过长参数列表:使用类/传入完整对象/合并为一个对象都可以有效的缩短参数列表,需要我们自己看情况决定。
5、全局数据:因为从代码库的任何角落都可以修改它,类变量和单例也有这种问题。对全局变量最好封装起来,限制它的作用域。
6、可变数据:对数据的修改经常导致出乎意料的结果和难以发现的bug。可变数据的作用域越大,风险也越大,同全局数据。
7、发散式变化:指某个模块经常因为不同的原因在不同的方向上发生变化。
8、霰(xiàn)弹式修改:指如果每遇到某种变化,你都必须在许多不同的类内作出许多小修改。
9、依恋情节:在模块化时一个函数跟另一个模块中的函数或者数据交流的格外频繁,远胜于在自己所处模块内部的交流。最好的办法当然是,将他们合并到一起。
10、数据泥团:指那些你常常在很多地方可以见到的相同的三四项数据,例如:两个类中相同的字段、许多函数签名中相同的参数等。最好的办法就是新建一个类,这样可以消除大量的重复。
11、基本类型偏执:指大量的使用基本类型,而很少创建对自己的问题域有用的基本类型。例如:把钱当做普通数字来计算、计算物理量时无视单位等。
12、重复的switch:指在不同的地方反复使用同样的switch逻辑(也可能是连续的if/else语句)。最佳的解决办法就是多态。
13、循环语句:使用管道操作来替代。至于什么是管道操作,看了后边的示例,主要指代filter和map,iOS没有这东西,JavaScript和Java的同学应该了解。
14、冗赘的元素:指那些简单的不需要搞的复杂的代码。例如:某个函数的名字和它的实现代码看起来一模一样,或者某个类根本就是一个简单的函数。
15、夸夸其谈通用性:主要指那些你以为将来会用到的代码。
16、临时字段:指仅为某种特定情况而设的字段。
17、过长的消息链:最好的办法是,先观察消息链最终得到的对象是用来干什么的,然后选择性的重构。
18、中间人:指过度运用委托。
19、内幕交易:指为了减少耦合而建起高墙。在实际情况中,一定的数据交换不可避免,我们必须尽量减少内幕交易这种情况,把这种交换都放到明面上。
20、过大的类:观察一个大类的使用者。经常能找到如何拆分类的线索。
21、异曲同工的类:使用类的好处之一就是可以替换,今天用这个类,未来可以换成另外一个。
22、纯数据类:指它们拥有一些字段,以及用于访问这些字段的函数,除此之外一无长物。纯数据类常常意味着行为被放到了错误的地方。也就是说,只要把处理数据的行为放到纯数据类中,就能是情况大为改观。不过一个非常常见的特殊情况就是,这个纯数据记录对象被用于函数调用的返回结果,此时无需操作。
23、被拒绝的遗赠:指子类继承了超类的所有函数和数据,但是它可能不想或者不需要继承,或者只需要其中的几样。此处建议:如果子类继承了超类的实现,却不愿意支持超类的接口,那就是不能被接受的。拒绝继承超类的实现可以被接受。
24、注释:注释可以帮我们找到重构的点,看到注释应该先想是否可以尝试重构。有用的注释一般指用来记录将来的打算,或者你暂时没有把握的内容,或者你为什么这么做。其他的注释就试试重构吧。

《重构》读后感(第二章)

第二章内容:为何重构。

重构与性能优化有很多相似之处:两者都需要修改代码,并且两者都不会改变程序的整体功能。不过两者的差别在于其目的:重构是为了让代码“更容易理解,更容易修改”,性能优化是为了让程序运行的更快。

为何重构:
1、改进软件的设计。
2、使软件更容易理解。
3、帮助找到bug。
4、提高编程速度:从长远来看。

何时重构:
有这么一个三次法则:第一次做某事时只管去做,第二次做类似的事情时会产生反感,但是还可以去做,第三次再做类似的事情,你就应该重构。正如老话:事不过三。
1、预备性重构:让添加新功能更容易。
2、帮助理解的重构:使代码更易懂。
3、捡垃圾式重构:清除垃圾代码。
以上三种都是见机行事类型的重构,遇到了顺便去做,或者记下稍后去做。这些应该是我们编程的一部分,让绝大多数的重构在我们的编程中自然而然的做到。剩下的就是:长期重构(有计划的重构) 和复审代码时重构。

何时不该重构:
第一条:我确定以后都不需要修改它,那我就可以不重构它。
第二条:为了API,暂时可以容忍。
第三条:如果重写比重构容易,那就重写吧,因为重构还得先理解整块代码。不过到底是重写还是重构,这实在不好建议,需要你或者你的leader根据自己丰富的经验来决定。

重构的挑战:
1、延缓新功能开发:显而易见。
2、代码所有权:是否有权限修改,是否会对其他人的代码造成较大的影响。
3、分支:在分支上工作越久,集成回主干的难度越大。建议:每天至少向主干提交一次(在我们这里是,每天都要将主干的代码合并到当前分支)。
4、测试:最好有可以自测试的代码。不然就需要我们的开发环境很好的支持自动化重构,或仅仅使用那些一定安全的重构手法。
5、遗留代码:往往很复杂,最关键的是这是别人写的,且没有相关的测试。
6、数据库。