最近在看Refactoring Improving the Design of Existing Code. 觉的遇到好的总结,方法和心得还是有必要记录下来,好记心不如烂笔头。
什么是重构——对软件内部结构的调整,在不改变软件可观察的行为的前提下提高可理解性,降低修改成本。
什么时候应该重构——代码的”坏味道“,当你面对代码时有这种直觉,那么这些代码就有必要重构了。 更多的这种“坏味道”需要靠经验来把握,不过也有一些所谓的原则,因人而已,适度把握好久行了。
好的测试是重构点的根本——算上大学时光,写代码也有几年了,可是测试这个习惯一直没有养成,加入现在的创业公司后,由于人员紧张所以我们的代码都是自己测试自己上线,没有了测试的保障问题就比较明显的凸显出来了,所以现在也开始着手写单元测试了,项目进度再紧张一定也要保证核心代码是有单元测试。
重构需要小碎步前进——很多时候看到了“坏代码“,内心就会痒痒,真心想全部推倒重来,可是当你动手去做的时候,发现重写这些代码实际上是一个非常大的工程,而且也不保证你写完的代码能比之前好多少,所以在面对这个问题的时候,需要一步一步平滑过渡,慢慢的就能把整个模块修改得美观清爽起来,这样即能跟上项目进度也能保证项目质量。
简短而命名良好的函数——这样做有三个好处
第一, 如果每个函数的力度都很小,那么函数被复用的机会就更大。
第二,可以使得高层函数读起来像一系列的注释一样。
第三,如果函数都是细粒度,那么函数的覆写也会更容易。
---------------------------------------2012.06.29--------------------------------------------------------
今天看完一章,发现没什么可记录的,最近在开发量比较大,开始有意思的用到书里提到的一些原则,技巧,发现还是挺有用。
---------------------------------------2012.07.06---------------------------------------------------------
在对象之间搬移特性
搬移函数 :在函数最常引用的类中建立一个有类似行为的新函数,将旧函数变成一个单纯的委托函数,或者将旧函数完全移除
搬移字段: 在目标类中建立一个新的字段,修改源字段的所有用户,令他们改用新字段。
提炼类:建立一个类,将相关的字段和函数从旧类搬移到新类。
将类内联化: 将这个类的所有特性搬移到另一个类中,然后移除原类。
隐藏委托关系: 在服务类上建立客户所需要的所有函数,用以隐藏委托,关系。
最近需要重构的代码以及重构数据处理框架比较多,重构大多时候是一种经验的行为,这些原则性的指导只有在能使得自己的项目变得更加简单的时候才是有意义的,否则 go to the hell。
--------------------------------------2012-07-08--------------------------------------------------------
重新组织数据
自封装字段:当你直接访问一个字段,但字段之间的耦合关系逐渐变的笨拙,那么为这个字段建立取值和设值函数。并且以这些函数来访问字段。
以对象取代数据值: 一个数据项需要与其他的数据和行为一起使用才有意义,那么将数据项变成对象。
将值对象改为引用对象:因从一个类衍生出许多彼此相等的实例,希望将他们替换为同一个对象,那么可以将这个值对象变成引用对象。
将引用对象改为值对象:一个应用对象,很小且不可变,而且不易管理,那么将它变为引用对象。
以对像取代数组: 以对像替换数组,对于数组中每一个元素用一个字段来替代。
--------------------------------------2012-07-09----------------------------------------------------------
简化条件表达式
分解条件表达式:将一个复杂的条件语句提炼出函数。
合并条件表达式:在一系列的条件表达式都得到来相同的结果,那么将这些条件合并位一个表达式并提炼为一个函数。
合并重复的条件片段:在条件表达式的每个分支上有着相同的一段代码,将这个重复的点代码搬移到条件表达式之外。
移除控制标记:
以卫语取代嵌套条件表达式:
以多态取代条件表达式:
引入段言。
---------------------------------------------2012-07-10------------------------------------------------------
简化函数调用
函数改名:函数应该能揭示用途。
添加参数:为此函数添加一个对象参数,让该对象参数带进函数所需要的信息。
移除参数:将查询函数和修改函数分离。
令函数携带参数:诺干函数做来相同的事情,但在函数本体中包含来不同的值。建立单一函数,以参数表达那些不同的值。
以明确函数取代参数:有一个函数,其中完全取决于参数值而采取不同行为,针对这个参数每一个可能的值,建立一个独立函数。
保持对象完整:从某个对象中取出诺干值,将他们作为一次调用的多个参数,那么这时候应该改为传递整个对象值。
以函数取代参数:对象调用某个函数,并将结果作为参数传递给另外一个函数。 而接受该参数的函数本身也能够调用前一个函数, 那么去掉这个参数的传递,直接调用函数。
引入参数对象:某些参数总是很自然的同时出现,那么可以一个对象取代这些参数。
以工厂函数替代构造函数:
封装向下转型:某个函数返回的对象,需要由函数调用着执行向下转型,将向下转型的的动作移动到函数中去。 (java里用的比较多)
以异常取代错误类型码。
-------------------------------------------------2012-07-12--------------------------------------------------------
处理概括关系
字段上移: 两个子类拥有相同的字段,那么将字段移至超类。
函数上移:有些函数,在各个子类中产生完全相同的结果,将函数移至超类。
构造函数本体上移: 在各个子类中拥有一些构造函数,他们的本体几乎完全一样,那么需要在超类中新建一个构造函数,并在子类构造函数中调用它。
函数下移:超类中某个函数只与部分子类相关,那么将这个函数移到相关的子类中去。
字段下移: 超类中某个字段只被部分子类拥有,那么将这个字段下移到对应的子类中去。
提炼子类:类中的某些特性只被某些实例用到,那么新建一个子类,将上面所说的那一部分特性移到子类中。
提炼超类:两个类有相似特性,那么为这两个类建立一个超类,将相同的特性移至超类中。
大型重构的几点原则:
每天一点点,而不是把一切推倒重来. 随着业务的发展,慢慢的对代码,对模块的功能,上下游关系,都有了进一步了解,小碎步式的重构才会更加构造出更加合理的代码,盲目的推倒重来难免不会上演现在代码的悲剧。 记住:每天都在使你的程序更加安全才是最重要的。
明确修改的方向, 在重构的过程中,整个团队都必须清楚的意识到:这是一个大的重构,每个人都应该清楚并准确的安排自己行动的方向。
简单。 重构后的整个架构,代码,逻辑以及和这些相关联的业务应该变的更加的简单并且灵活
最近也在考虑重构公司的数据流架构,对于一个广告公司来说,数据流可以说是最重要的一条生命线,从我们最近遇到的一些线上事故来看这么说已不为过了。那么本次重构我也会更加的小心谨慎,大致也会按照如下的一些步骤进行,实践才能出真知。
梳理并分解类继承体系: 这个继承体系可以说是整个项目的一个主心骨,它也就是大型重构的第二条原则,有了这个东西那么就能明确了修改的方向。
将过程化设计转化为对象设计:将数据记录变成对象,将大块行为分成小块,并将行为移入相关对象之中。
--------------------------------------------2012-07-15------------------------------------------------