像工匠一样进行重构, 让重构成为一门手艺.
Martin Fowler的《Refactoring》其实更适合做一本关于重构的洗脑,宣言式的书,就像Kent Beck的《XP Explain》一样薄薄的就可以了。只可惜他却非常的厚,后面的重构名录都是写给小白看的。所以我更喜欢《Refacoring WorkBook》,以一个工匠的语气(沉默寡言而实要)传授重构的手艺。
1.重构 Between Classes
〈Design pattern〉有半数篇幅教育大家不能只靠继承,要善用组合/委托。重构里面其实也有很多事情靠把继承变成委托来解决。
1.1继承
1.1.1 并行继承体系,组合爆炸
这在以前是个头痛的问题,现在都已习惯用委托。
另外java还有个不是很让人满意的接口机制解决并行继承。
1.1.2 父子类的关系
比如过于亲密,子类会乱修改父类的方法,访问父类的变量,这时候可以定义final的Template方法。
还有拒绝的馈赠,我暂时还没有在这上面遇到问题,作者也建议如果没事就由他,如果有事,就要费劲的move method ;或者子类不继承父类,而只是组合父类。
1.2职责
经过很多次重构之后,我发现,其实哪个方法应该放在哪个类其实很主观的,你每天醒来都能想到一个理由让一个方法搬一下家,所以我现在已经放弃追求一种“对”的职责分配了,看着顺眼就行。
1.3散弹式修改
作一个修改就要改N个类时,也没什么特别好方法,就是找找看,有没有能为这个修改负责的统管全局的类。
但现在的很多散弹式修改是分层做成的。
1.4库类
OpenSource的类库,总有些时候会想要扩展
1.如果只是一两个方法,直接在客户代码里扩展,
2.否则自己多一个类库的子类
3.最费劲就是引入一个新的层
题外话,重构其实很依赖工具,和对全部代码的拥有度,哗一下就来个全项目的rename。当你设计库类时,你并不一定拥有使用这些库类的客户代码了,因此一开始就要认真设计,不能依赖重构,改接口会让人K死的。
2.重构 Within Classes
2.1 大是罪
Long Method、Large Class、Long Parameter List, 一般通过度量工具找出来,还可以自己设定一个触发器,当度量值超过某个限度时就报警。
PMD可以实现这个功能,但度量工具我更喜欢Metrics Reload,一个IDEA的插件,给出的度量信息很全面。
但是也切忌为了度量的数值而重构。
Long Method当然是尝试Extract Method。
Large Class就要把类的职能分开几个域,尝试拆出另一个Class或者SubClass。
Long Parameter List 可以通过在方法内的变量用查询获得而不用由参数传入;
或者把某些参数组成一个对象。
1.2 重复也是罪
重复在30年前就被认为是不好的一样东西,表现在1.代码类似,2.代码、接口不同而作用相近。
去除重复的方法也没什么特别,无非就是
Extract Method(同一个类)。有差异时,通过参数化达到共用。
Pull Up Method到父类(同一个父类)。有差异时,通过模板机制达到共用。
Class A调用Class B 或者 Extract Class C (两个完全无相干的类)
1.3 命名
中国程序员的英文本来就差,要多参考Ofbiz、Comperie的命名, 尽快建立团队的项目字典、领域术语字典。
也幸亏,现在在工具辅助下,代码的rename是最容易的重构。
1.4复杂条件表达式
作者认为,即使现在Program最关注的是对象,以及对象间的关系了,但优质的内部代码依然重要,推荐《编程珠玑》和《Elements of Programing style》。
化简复杂条件的基本有三个方法
1.通过!(A&B)==(!A)||(!B)化简
2.通过有意义的变量,函数代替条件表达式,比如
boolean isMidScore = (X>1000)&&(X<3000);
3.通过把一个if拆分开来执行,把guard clause放在前面
比如if(A||B)
do();
->if(A)
do();
if(B)
do();
又可以把2、3灵活组合,比如根据2,Extract出一个isRight()函数,根据3
isRight()
{
if(A)
return true;
if(B)
return true;
return false;
}
1.5 其他
没用的死代码,通过IDE工具探知并移除。小心有些框架代码是不能删除的。
Magic Number,当然是改为常量。如果Magic Number很多,可以用Map、枚举类来存放。
除臭剂式的注释,为方法,变量改一个更适合的名字。如果注释是针对一个代码段的,可以Extract Method。当然,代码只能说明how, 不能说明why,更不能说明why not,这才是注释存在的地方。
分享到:
相关推荐
值得注意的是,尽管这个插件极大地提升了PHP开发者的生产力,但进行重构时仍需谨慎。在进行大规模重构前,最好先备份项目,以免意外修改导致问题。同时,定期更新插件以获取最新的功能和修复的bug也是必要的。 总之...
《Professional Refactoring Workbook》是一本专注于软件重构的专业书籍,旨在帮助开发者提升代码质量和可维护性。重构是软件开发过程中的一个重要环节,它涉及到在不改变软件外在行为的前提下,改进其内部结构,...
在添加新功能或修复bug时,是进行重构的好时机。这不仅可以避免新代码进一步恶化现有的设计,而且可以在理解现有代码的基础上更有效地扩展功能。同时,书中也指出,重构不应被视为一次性的大工程,而是应作为持续...
《重构手册 Professional Refactoring Workbook》是一本专注于软件重构实践的权威指南。本书旨在帮助开发者们理解和掌握重构这一关键技能,以提升代码质量、可维护性和软件设计的灵活性。重构是软件开发过程中的一个...
如果不进行重构,随着时间的推移,这些系统可能会变成所谓的“遗产系统”或“技术债务”,这将导致开发新功能变得更加困难且耗时。通过重构,开发人员可以逐步清理代码库,使其保持健康的状态,从而能够快速响应新的...
vim-ruby-refactoring, 在vim中,用于 ruby的重构工具 ! 用于Vim的 ruby-重构工具我喜欢 vim 当我开发软件的时候,它是我的选择编辑器。目前( 至少在过去的4年中) 主要使用 ruby 编程语言。在开发过程中,我一直...
某些项目如Extract Method和Move Field看起来可能很浅显,但不要掉以轻心,因为理解这类技术正是有条不紊地进行重构的关键。本书所提的这些重构准则将帮助你壹次壹小步地修改你的代码,这就减少了过程中的风险。很快...
该书讨论如何在现有代码的基础上重构,并加入新代码的各种具体的思路和方法
### 31天重构指南——代码重构(Refactoring) #### 一、代码重构的基本概念 代码重构是指在不改变程序外部行为的前提下,对其内部结构进行调整的过程。这一做法旨在提高程序的质量,包括但不限于提高代码的可读性...
VIMPHP重构工具箱重命名局部变量重命名类变量重命名方法提取用途提取常量提取类属性提取方法建立财产检测未使用的使用声明对齐分配创建setter和getter 记录所有代码安装 : Plug 'adoy/vim-php-refactoring-...
在Ruby中进行重构,需要开发者熟悉其语言特性,比如动态类型、块(block)、混入(mixin)等,以便更加高效地改进代码。 文档中出现的大量重复链接“更多资源请访问稀酷客(***)”可能是某种出版商或者版权信息的...
这本书不仅对重构技术进行了深入探讨,还整理归纳了超过70种行之有效的重构方法,对软件工程师而言,它与《设计模式》一样,成为了一部不可或缺的经典之作。 重构技术在编程高手的小圈子中流传已久,但其普及程度...
重构-改善既有代码的设计(Refactoring Improving the Design of Existing Code)
他提倡TDD(测试驱动开发)模式,先写测试,再编写满足测试的代码,最后进行重构,这有助于保持代码的正确性。 此外,书中还讨论了何时应该重构,以及如何识别需要重构的代码。通过分析代码的坏味道,如过长的方法...
重构-改善既有代码的设计重构-改善既有代码的设计重构-改善既有代码的设计
我们的任务是使用挂钩将整个代码重构为功能组件,并将Typescript添加到应用程序中。 :kick_scooter: 学习概念的最佳方法是动手,重构整个代码确实在您的脑海中。 :satellite_antenna: 如何运行项目克隆项目并访问...
为了更好地指导读者,书中不仅提供了何时进行重构的指示,还提供了实际操作中的逐步指令。每个重构方法都有一个或多个具体的例子,这些例子展示了重构的具体过程和效果。 Martin Fowler不仅仅是本书的作者,他还是...