代码重构二

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

代码重构(二)代码的坏味道与一般重构方法序号代码的坏味道一般重构方法1重复代码提炼方法提取类方法上移替换算法链构造方法2过长方法提取方法组合方法以查询取代临时变量引入参数对象保持对象完整代码的坏味道与一般重构方法序号代码的坏味道一般重构方法1重复代码提炼方法提取类方法上移替换算法链构造方法2过长方法提取方法组合方法以查询取代临时变量引入参数对象保持对象完整代码的坏味道与一般重构方法序号代码的坏味道一般重构方法3过长参数列以方法取代参数引入参数对象保持对象完整4条件逻辑过度复杂分解条件式合并条件式合并重复的条件片段移除控制标记以卫语句取代嵌套条件式以多态取代条件式引入断言代码的坏味道与一般重构方法代码的坏味道与一般重构方法序号代码的坏味道一般重构方法5分支语句提取方法转移方法以子类取代类型代码以多态取代条件式已明确方法取代参数6基本类型迷恋程序代码过于依赖基本类型(int,string,double,array等低层次语言要素)以对象取代数据值以类型取代类型代码以子类取代类型代码提取类引入参数对象以对象取代数组代码的坏味道与一般重构方法代码的坏味道与一般重构方法序号代码的坏味道一般重构方法7数据泥团在类的字段和参数列中,总是一起出现的数据提取类引入参数对象保持对象完整8令人迷惑的临时字段提取类9组合爆炸许多段代码使用不同种类或数量的数据或对象做同样的事情(例如使用特定条件和数据库查询)10过大类提取类提取子类提取接口复制被监视数据代码的坏味道与一般重构方法代码的坏味道与一般重构方法序号代码的坏味道一般重构方法11冗赘类不再做很多工作或没有用的类折叠继承关系内联Singleton12不恰当的暴露在客户代码中不应看到类的字段和方法,却是公开可见的封装字段封装群集移除设置方法隐藏方法13发散式变化类经常因为不同的原因在不同方向上发生变化,显然是违反了单一职责原则提取类代码的坏味道与一般重构方法代码的坏味道与一般重构方法序号代码的坏味道一般重构方法14霰弹式修改如果遇到变化,必须在不同的类中作出相应的修改转移方法转移字段内联类15依恋情结方法对于某个类的兴趣高过对自己所处的宿主类转移方法提取方法16平行继承体系当为一个类增加一个子类时,也必须在另一个类中增加一个相应的子类转移方法转移字段代码的坏味道与一般重构方法代码的坏味道与一般重构方法序号代码的坏味道一般重构方法17夸夸其谈未来性折叠继承关系内联类移除参数移除方法18过度耦合的消息连不断的向一个对象索求另一个对象隐藏委托提取方法转移方法19中间转手人类接口中有很多方法都委托给其他类移除中间转手人内联方法以继承取代委托代码的坏味道与一般重构方法序号代码的坏味道一般重构方法20狎昵关系类之间彼此依赖于其private成员转移方法将双向关联改为单向提取类隐藏委托以继承取代委托21异曲同工的类重命名方法转移方法提取超类代码的坏味道与一般重构方法序号代码的坏味道一般重构方法22不完善的程序库类引入外加方法引入本地扩展23纯稚的数据类只拥有字段的数据类封装字段封装集合移除设置方法转移方法隐藏方法代码的坏味道与一般重构方法代码的坏味道与一般重构方法序号代码的坏味道一般重构方法24被拒绝的遗赠继承父类时,子类想要选择继承的成员以委托取代继承25过多的注释为糟糕的代码写大量的注释使用一起重构方法,使方法本身达到自说明的效果,让注释显得多余26怪异解决方案在同一系统中使用不同的方式解决同一问题替换算法重构技巧重新组织你的函数在对象之间搬移特性重新组织数据简化条件表达式简化函数调用处理概括关系重新组织函数ExtractMethod(提炼函数)InlineMethod(内联函数)InlineTemp(内联临时变量)ReplaceTempwithQuery(以查询取代临时变量)IntroduceExplainingVariable(引入解释性变量)SplitTemporaryVariable(分解临时变量)RemoveAssignmentstoParameters(移除对参数的赋值)ReplaceMethodwithMethodObject(以函数对象取代函数)SubstituteAlgorithm(替换算法)ExtractMethods(提炼函数1)Stringname=request.getParameter(Name);if(name!=null&&name.length()0){......}Stringage=request.getParameter(Age);if(age!=null&&age.length()0){......}Stringname=request.getParameter(Name);if(!isNullOrEmpty(name)){......}Stringage=request.getParameter(Age);if(!isNullOrEmpty(age)){......}privatebooleanisNullOrEmpty(finalStringstring){if(string!=null&&string.length()0){returntrue;}else{returnfalse;}}ExtractMethods(提炼函数2:清除注释)voidprintOwing(){//printbannerSystem.out.println(“*********”);System.out.println(“Banner”);System.out.println(“*********”);//printdetailsSystem.out.println(name:+_name);System.out.println(amount+getOutstanding());}voidprintOwing(){printBanner();printDetails(getOutstanding());}voidprintBanner(){System.out.println(“*********”);System.out.println(“Banner”);System.out.println(“*********”);}voidprintDetails(doubleoutstanding){System.out.println(name:+_name);System.out.println(amount+outstanding);}InlineMethod(将函数内联化)InlineTemp(将临时变量内联化)ReplaceTempwithQuery(以查询取代临时变量)doublebasePrice=_quantity*_itemPrice;if(basePrice1000)returnbasePrice*0.95;elsereturnbasePrice*0.98;if(basePrice()1000)returnbasePrice()*0.95;elsereturnbasePrice()*0.98;...doublebasePrice(){return_quantity*_itemPrice;}IntroduceExplainingVariable(引入解释性变量)booleanisMacOs=platform.toUpperCase().indexOf(MAC)-1;booleanisIEBrowser=browser.toUpperCase().indexOf(IE)-1;booleanwasResized=resize0;if(isMacOs&&isIEBrowser&&wasInitialized()&&wasResized){//dosomething}if((platform.toUpperCase().indexOf(MAC)-1)&&(browser.toUpperCase().indexOf(IE)-1)&&wasInitialized()&&resize0){//dosomething}SplitTemporaryVariable(分解临时变量)doubletemp=2*(_height+_width);System.out.println(temp);temp=_height*_width;System.out.println(temp);doubleperimeter=2*(_height+_width);System.out.println(perimeter);doublearea=_height*_width;System.out.println(area);RemoveAssignmentstoParameters(移除对参数的赋值)ReplaceMethodwithMethodObject(以函数对象取代函数)SubstituteAlgorithm(替换算法)在对象之间搬移特性搬移函数(MoveMethod)搬移值域(MoveField)提炼类(ExtractClass)将类内联化(InlineClass)隐藏[委托关系](HideDelegate)移除中间人(RemoveMiddleMan)引入外加函数(IntroduceForeignMethod)引入本地扩展(IntroduceLocalExtension)1、MoveMethod(搬移函数)如果一个方法与其sourceclass之外的另一个class进行更多的交流(调用或者被调用),就在另一个class中建立一个类似行为的新方法。将原来的方法变成一个委托方法(delegatingmethod),或者将其完全删除。MoveMethod(搬移函数)在搬移过程中,如果该方法需要使用sourceclass的特性,有以下几种选择:1、将该特性也移到targetclass2、建立或使用一个从targetclass到sourceclass的引用关系3、讲sourceobject当作参数传给targetmethod4、如果需要特性是个变量,将它作为参数传给targetmethod搬移值域(MoveField)如果一Field被其sourceclass之外的另一个class进行更多的用到。就在targetclass中建立一个新的Field,修改sourcefield的所有用户,令它们改用新的field。必须删除sourcefield才能保证访问函数的确改变了操作对象。搬移值域(MoveField)publicclassMoveMethod{privateAccountType_type;privatedouble_interestRate;publicdoubleInterestForAmountDay(doubleamount,intdays){return_interestRate*amount*days/365;}}publicclassAccountType{}搬移值域(MoveField)publicclassMoveMethod{privateAccountType_type;publicdoubleInterestForAmountDay(doubleamount,intdays){return_type.InterestRate*amount*days/365;}}publicclassAccountType{privatedouble_interestRate;publicdoubleInterestRate{get{return_interestRate;}set{_interestRate=value;}}}提炼类(ExtractClass)一个class做了过多的工作,就应建立一个新的class,将多余特性相关的Field和Method从sourceclass搬移到targetclass。一个class应该是一个清楚的抽象,处理一些明确的责任。将类内联化(InlineClass)如

1 / 97
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功