最近在对已有项目进行扩展的时候,发现要改动的一个类它长766行,开放了近40个public接口,我流着泪把它给改完了。为了防止这样的惨剧再次发生在个人身上,我以为有必要写一篇博客来让广大程序猿同胞知道代码重构的重要性运维
若是你身边有一个类写上千行的猿,必定要把此文转给ta函数
此时CV工程师打了个冷战测试
冗余代码,就是重复代码,一般出自使用Ctrl+C,Ctrl+V来生产代码的CV工程师之手,冗余代码的危害很是大:设计
一个类开放几十个接口,绝对存在职责过多的问题,就像图中的Tom猫同样手忙脚乱,一个类的职责过多也有巨大问题:cdn
违反设计原则——单一职责原则(单一职责原则要求一个类只实现一个职责,好比一只Tom只作扫地、擦桌、拖地中的一件事,而其余事的实现能够转移给史派克狗或肥胖女佣),违反了这个原则会致使发散式变化、发散式修改、类过长等代码问题,还会让你的类难以扩展,甚至会让其余程序猿认为你不专业对象
发散式变化(指引起此类修改的地方不少),若是一个类的职责不少,那它的扇入(调用者)必定不少,每一个调用者的修改都有可能让你这个类不得不随之修改,也就是发散式变化blog
就是说无论哪儿出了问题,你这个类都得遭殃接口
发散式修改(指此类修改引起修改的地方不少),相同的,若是一个类职责不少,那支撑它实现的下级,即扇出(被调用方)必定不少,若是此类逻辑发生变更,全部下级被调用者可能都得随之修改,也就是发散式修改get
就是说你这个类出了问题,无论哪儿都会遭殃博客
难以扩展:若是你的一个类接口很是多,那它的子类怎么办?它的包装类怎么办?难道所有都要实现这么多接口,所有都要承担一样多的职责吗?扩展起来真的很是麻烦
触发机关:【测试之怒】【运维之怒】
抽取冗余代码就是将重复代码抽取成一个独立的方法,以后再使用这段代码时就再也不须要Ctrl + C,Ctrl + V,而是直接调用对应的方法便可
这样作也能够缩短原方法,使原方法更加简洁易懂
更值得一提的是若是这段代码须要修改,也只需修改一处,而不是发散式地处处修改
真是一箭三雕
找到重复代码
进行方法抽取 右键->选择重构->抽取->方法 (或者直接使用快捷键Ctrl + Alt + m)
自动检测出个别重复代码的细微差异,有些代码可能只改动一两个变量,IDEA会自动检测出来,并在抽取方法时提醒咱们,选择左侧Accept Signature Change(接受签名变更)可使抽取的方法自动替换更多的重复点
能够选择替换掉全部的重复代码(居然有18处)
重构——更改方法签名
若是你对抽取出的方法的名字、参数、返回值或是修饰符不满意,不要使用Ctrl + R 修改,IDEA提供了重构方法——更改签名(快捷键Ctrl + F6)
注意:方法的名字指的是方法作了什么,而非怎么去作,最好是 动词+名词 格式
好比:Tom.扫地() √
Tom.扫地With扫把() ×
Tom.用扫把扫地() ×
将不该该由本身管理的成员变量和函数转移出去
那就要考虑两个问题:该转移谁?转移给谁?
来看一个图
注意,先决定移动哪一个成员变量,而后再决定移动哪一个函数
移动成员变量,鼠标选择成员变量->右键->Refactor->Move,而后选择转移至哪一个类
移动函数(与移动成员变量步骤相同)
当你发现要转移的成员变量和函数找不到合适的类时(转移职责却找不到下家),要想起来,这里是程序世界,而咱们程序猿就是类和对象的造物主,是时候建立一个新的类,让它来替咱们分担职责(成员变量和函数)了
重构 选中要搬的成员变量和函数,右键->Refactor->Extract->Delegate(抽取一个委托者,委托他来管理这部分变量和函数,若是只有变量或只有函数,能够抽出参数对象Paramater Object或方法对象Method Object)
不推荐抽取参数对象,由于通常参数对象是给参数多的方法用的(用参数对象取代一长溜的参数),并且若是成员变量抽取了也不会影响任何函数的话,那就是无用对象了,不如直接把他们删除掉
为新类起个名,选个包吧
注意,抽取的函数和成员必定要符合一个原则,那就是被抽取函数使用被抽取成员的次数必定高于剩余函数的次数,否则违反亲密性原则(成员应归于调用它最多的类,没有理由你用的比我多还让我来管理)
一些小问题
因为抽取的函数直接使用了未抽取的对象而致使重构失败,涉及到另外一个重构(使用get方法而非直接使用私有成员变量),使用此重构便可解决