《《重构技术教程》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《重构技术教程》PPT课件.ppt(42页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、重构技术重构技术邱百超badqiu(a)讲解内容讲解内容l重构介绍l重构原则l代码的坏味道l重构技巧l重构工具使用实例lQ&A名言名言 l任何一个傻瓜都能写出计算机可以理解的程序,只有写出人类容易理解的程序才是优秀的程序员 Martin Fowler什么是重构什么是重构lRefactoring是对软件内部结构的一种调整,目的是在不改变外部行为的前提下,提高其可理解性,降低其修改成本。为什么重构为什么重构l改进软件的设计。l程序员对代码所做的为了满足短期利益代码改动,或再没有完全清楚增个架构下的改动,都很容易是代码失去它的清晰结构,偏离需求或设计。而这些改动的积累很容易使代码偏离它原先设计的初衷
2、而变得不可立即和无法维护。lRefactoring则帮助重新组织代码,重新清晰的体现结构和进一步改进设计。为什么重构为什么重构l提高代码质量,更易被理解l容易理解的代码可以很容易的维护和做进一步的开发。即使对写这些代码的程序员本身,容易理解代码也可以帮助容易地做修改。程序代码也是文档。而代码首先是写给人看的,让后才是给计算机看的。为什么重构为什么重构lRefactoring帮助尽早的发现错(Bugs)lRefactoring是一个code review和反馈的过程。在另一个时段重新审视自己或别人代码,可以更容易的发现问题和加深对代码的理解。lRefactoring是一个良好的软件开发习惯。为什
3、么重构为什么重构lRefactoring可以提高开发速度lRefactoring对设计和代码的改进,都可以有效的提高开发速度。好的设计和代码质量实体提高开发速度的关键。在一个有缺陷的设计和混乱代码基础上的开发,即使表面上进度较快,但本质是试延后对设计缺陷的发现和对错误的修改,也就是延后了开发风险,最终要在开发的后期付出更多的时间和代价。l项目的维护成本远高于开发成本.何时重构何时重构?l添加新功能时一并重构l为了增加一个新的功能,程序员需要首先读懂现有的代码。l修补错误时一并重构l为了修复一个Bug,程序员需要读懂现有的代码。lCode Review时一并重构何时不该重构何时不该重构?l代码太
4、混乱,设计完全错误。与其Refactor,不如重写。l明天是DeadLinel永远不要做Last-Minute-Change。推迟Refactoring,但不可以忽略,即使进入Production的代码都正确的运行。lRefactoring的工作量显著的影响最后期限l一个Task的计划是天,如果为了Refactoring,需要更多的时间(天或更多)。推迟Refactoring,同步可以忽略。可以把这个Refactoring作为一个新的Task,或者安排在Refactoring的Iteration中完成。两顶帽子两顶帽子l重构重构与添加新功能添加新功能l添加新功能时,你不应该修改既有代码,只管添
5、加新功能。l重构时你就不能再添加功能,只管改进程序结构。此外你不应该添加任何测试(除非发现有先前遗漏的东西)l两顶“帽子”可同时进行,一会重构,一会添加新功能。重构与设计重构与设计 l重构可以从很大程度上去扶助设计,通常情况下我们的设计不是能贯穿我们软件开发的全过程的,在这个过程中,我们的需求变更的可能性非常大,当需求变了,设计也得变,但是我们已有的实现怎么办?全部废除?显然不能!这时候就要依靠重构来解决这种矛盾。重构与性能重构与性能 l关于重构,有一个常被提出的问题:它对程序的性能将造成怎样的影响?为了让软件易于理解,你常会作出一些使程序运行变慢的修改。这是个重要的问题。我并不赞成为了提高设
6、计的纯洁性或把希望寄托于更快的硬件身上,而忽略了程序性能。已经有很多软件因为速度太慢而被用户拒绝,日益提高的机器速度亦只不过略微放宽了速度方面的限制而已。但是,换个角度说,虽然重构必然会使软件运行更慢,但它也使软件的性能优化更易进行。关键在于自己的理解,当你拥有了重构的经验,你也就有能力在重构的基础上来改进程序的性能。重构与模式重构与模式l那么真正要实现重构时,我们有哪些具体的方法呢?可以这样说,重构的准则由很多条,见重构这本书。但它不是最终的标准,因为你要是完全按照它的标准来执行,那你也就等于不会重构,重构是一种武器,而真正运用武器的高手是没有武器胜有武器。只有根据实际的需要,凭借一定的思想
7、,才能实现符合实际的重构,我们不能被一些固定的模式套牢了,这样你的程序会很僵化。究竟如何把握这个度,需要大家去总结。重构与思想重构与思想 l要想实现一个好的重构,不是重构本身,而是我们在写代码的时候,思想当中时刻有它的位置存在!非常重要!如果你本身就没想着要去重构,那么就是有再好的模式供你调用又怎么样?就是有了好的模式,你不能根据实际的需要去融会贯通,那你做出来的重构有意义么?应用范围应用范围l代码重构l网页重构l设计重构l.Refactoring的流程的流程l流程1l读懂代码(包括测试例子代码)lRefactoringl运行所有的Unit Testsl流程2l读懂代码l应用重构工具进行重构(
8、如Eclipse)代码坏味道代码坏味道l重复的代码(Duplicated Code)l过长的函数(Long Method)l过大类(Large Class)l过长的参数列(Long Parameter List)l发散式变化(Divergent Change)l霰弹式修改(Shotgun Surgery)l依恋情结(Feature Envy)l数据泥团(Data Clumps)l基本型别偏执(Primitive Obsession)lSwitch语句(Swtich Statements)l平行继承体系(Parallel Inheritance Hierarchies)l冗赘类(Lazy Cla
9、ss)l夸夸其谈未来性(Speculative Generality)l令人迷惑的暂时值域(Temporary Field)l过度遇合的消息链(Message Chains)l中间转手人(Middle Man)l狎昵关系(Inappropriate Intimacy)l异曲同工的类(Alternative Classes with Different Interfaces)l不完善的程序库类(Incomplete Library Class)l纯粹的数据类(Data Class)l被拒绝的遗赠(Refused Bequest)l过多的注释(Comments)重构技巧重构技巧l重新组织你的函数l
10、在对象之间搬移特性l重新组织数据l简化条件表达式l简化函数调用l处理概括关系Extract Methods(提炼函数提炼函数1)String name=request.getParameter(Name);if(name!=null&name.length()0).String age=request.getParameter(Age);if(age!=null&age.length()0).String name=request.getParameter(Name);if(!isNullOrEmpty(name).String age=request.getParameter(Age);if
11、(!isNullOrEmpty(age).private boolean isNullOrEmpty(final String string)if(string!=null&string.length()0)return true;elsereturn false;Extract Methods(提炼函数:提炼函数:清除注释)清除注释)void printOwing()/print bannerSystem.out.println(“*”);System.out.println(“Banner”);System.out.println(“*”);/print detailsSystem.out
12、.println(name:+_name);System.out.println(amount +getOutstanding();void printOwing()printBanner();printDetails(getOutstanding();void printBanner()System.out.println(“*”);System.out.println(“Banner”);System.out.println(“*”);void printDetails(double outstanding)System.out.println(name:+_name);System.ou
13、t.println(amount +outstanding);Inline Method(将函数内联化将函数内联化)Inline Temp(将临时变量内联化)(将临时变量内联化)Replace Temp with Query(以(以查询取代临时变量)查询取代临时变量)double basePrice=_quantity*_itemPrice;if(basePrice 1000)return basePrice*0.95;elsereturn basePrice*0.98;if(basePrice()1000)return basePrice()*0.95;elsereturn basePric
14、e()*0.98;.double basePrice()return _quantity*_itemPrice;Introduce Explaining Variable(引入解释性变量)(引入解释性变量)boolean isMacOs =platform.toUpperCase().indexOf(MAC)-1;boolean isIEBrowser=browser.toUpperCase().indexOf(IE)-1;boolean wasResized =resize 0;if(isMacOs&isIEBrowser&wasInitialized()&wasResized)/do so
15、methingif(platform.toUpperCase().indexOf(MAC)-1)&(browser.toUpperCase().indexOf(IE)-1)&wasInitialized()&resize 0)/do something Split Temporary Variable(剖解(剖解临时变量)临时变量)double temp=2*(_height+_width);System.out.println(temp);temp=_height*_width;System.out.println(temp);double perimeter=2*(_height+_wid
16、th);System.out.println(perimeter);double area=_height*_width;System.out.println(area);Remove Assignments to Parameters(移除对参数的赋值)(移除对参数的赋值)Replace Method with Method Object(以函数对象取代函数)(以函数对象取代函数)Substitute Algorithm(替换算法)(替换算法)Replace Nested Conditional with Guard Clauses double getPayAmount()double r
17、esult;if(_isDead)result=deadAmount();else if(_isSeparated)result=separatedAmount();else if(_isRetired)result=retiredAmount();else result=normalPayAmount();return result;double getPayAmount()if(_isDead)return deadAmount();if(_isSeparated)return separatedAmount();if(_isRetired)return retiredAmount();r
18、eturn normalPayAmount();Split Loop-1void printValues()double averageAge=0;double totalSalary=0;for(int i=0;i people.length;i+)averageAge+=peoplei.age;totalSalary+=peoplei.salary;averageAge=averageAge/people.length;System.out.println(averageAge);System.out.println(totalSalary);void printValues()doubl
19、e totalSalary=0;for(int i=0;i people.length;i+)totalSalary+=peoplei.salary;double averageAge=0;for(int i=0;i people.length;i+)averageAge+=peoplei.age;averageAge=averageAge/people.length;System.out.println(averageAge);System.out.println(totalSalary);Split Loop-2void printValues()System.out.println(av
20、erageAge();System.out.println(totalSalary();private double averageAge()double result=0;for(int i=0;i people.length;i+)result+=peoplei.age;return result/people.length;private double totalSalary()double result=0;for(int i=0;i people.length;i+)result+=peoplei.salary;return result;简化条件表达式简化条件表达式分解表达式分解表
21、达式if(date.before(SUMMER_START)|date.after(SUMMER_END)charge=quantity*_winterRate+_winterServiceCharge;elsecharge=quantity*_summerRateif(notSummer(date)charge=winterCharge(quantity);elsecharge=summerCharge(quantity);Remove Double Negativeif(!item.isNotFound()if(item.isFound()在对象之间搬移特性在对象之间搬移特性l搬移函数(M
22、ove Method)l搬移值域(Move Field)l提炼类(Extract Class)l将类内联化(Inline Class)l隐藏委托关系(Hide Delegate)l移除中间人(Remove Middle Man)l引入外加函数(Introduce Foreign Method)l引入本地扩展(Introduce Local Extension)重构工具重构工具lJava:EclipselC#:Visual Studio 插件:ReSharper lC+:?演示演示Eclipse重构的使用重构的使用参考参考l重构:改善即有代码的设计-Martin FowlerlRefactoringQ&A谢谢谢谢!