资源预览内容
第1页 / 共42页
第2页 / 共42页
第3页 / 共42页
第4页 / 共42页
第5页 / 共42页
第6页 / 共42页
第7页 / 共42页
第8页 / 共42页
第9页 / 共42页
第10页 / 共42页
亲,该文档总共42页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
重构技术,邱百超 badqiu(a)gmail.com,讲解内容,重构介绍 重构原则 代码的坏味道 重构技巧 重构工具使用实例 Q&A,名言,任何一个傻瓜都能写出计算机可以理解的程序,只有写出人类容易理解的程序才是优秀的程序员 Martin Fowler,什么是重构,Refactoring是对软件内部结构的一种调整,目的是在不改变外部行为的前提下,提高其可理解性,降低其修改成本。,为什么重构,改进软件的设计。 程序员对代码所做的为了满足短期利益代码改动,或再没有完全清楚增个架构下的改动,都很容易是代码失去它的清晰结构,偏离需求或设计。而这些改动的积累很容易使代码偏离它原先设计的初衷而变得不可立即和无法维护。 Refactoring则帮助重新组织代码,重新清晰的体现结构和进一步改进设计。,为什么重构,提高代码质量,更易被理解 容易理解的代码可以很容易的维护和做进一步的开发。即使对写这些代码的程序员本身,容易理解代码也可以帮助容易地做修改。程序代码也是文档。而代码首先是写给人看的,让后才是给计算机看的。,为什么重构,Refactoring帮助尽早的发现错(Bugs) Refactoring是一个code review和反馈的过程。在另一个时段重新审视自己或别人代码,可以更容易的发现问题和加深对代码的理解。 Refactoring是一个良好的软件开发习惯。,为什么重构,Refactoring可以提高开发速度 Refactoring对设计和代码的改进,都可以有效的提高开发速度。好的设计和代码质量实体提高开发速度的关键。在一个有缺陷的设计和混乱代码基础上的开发,即使表面上进度较快,但本质是试延后对设计缺陷的发现和对错误的修改,也就是延后了开发风险,最终要在开发的后期付出更多的时间和代价。 项目的维护成本远高于开发成本.,何时重构?,添加新功能时一并重构 为了增加一个新的功能,程序员需要首先读懂现有的代码。 修补错误时一并重构 为了修复一个Bug,程序员需要读懂现有的代码。 Code Review时一并重构,何时不该重构?,代码太混乱,设计完全错误。与其Refactor,不如重写。 明天是DeadLine 永远不要做Last-Minute-Change。推迟Refactoring,但不可以忽略,即使进入Production的代码都正确的运行。 Refactoring的工作量显著的影响最后期限 一个Task的计划是天,如果为了Refactoring,需要更多的时间( 天或更多)。推迟Refactoring,同步可以忽略。可以把这个Refactoring作为一个新的Task,或者安排在Refactoring的Iteration中完成。,两顶帽子,重构与添加新功能 添加新功能时,你不应该修改既有代码,只管添加新功能。 重构时你就不能再添加功能,只管改进程序结构。此外你不应该添加任何测试(除非发现有先前遗漏的东西) 两顶“帽子”可同时进行,一会重构,一会添加新功能。,重构与设计,重构可以从很大程度上去扶助设计,通常情况下我们的设计不是能贯穿我们软件开发的全过程的,在这个过程中,我们的需求变更的可能性非常大,当需求变了,设计也得变,但是我们已有的实现怎么办?全部废除?显然不能!这时候就要依靠重构来解决这种矛盾。,重构与性能,关于重构,有一个常被提出的问题:它对程序的性能将造成怎样的影响?为了让软件易于理解,你常会作出一些使程序运行变慢的修改。这是个重要的问题。我并不赞成为了提高设计的纯洁性或把希望寄托于更快的硬件身上,而忽略了程序性能。已经有很多软件因为速度太慢而被用户拒绝,日益提高的机器速度亦只不过略微放宽了速度方面的限制而已。但是,换个角度说,虽然重构必然会使软件运行更慢,但它也使软件的性能优化更易进行。关键在于自己的理解,当你拥有了重构的经验,你也就有能力在重构的基础上来改进程序的性能。,重构与模式,那么真正要实现重构时,我们有哪些具体的方法呢?可以这样说,重构的准则由很多条,见重构这本书。但它不是最终的标准,因为你要是完全按照它的标准来执行,那你也就等于不会重构,重构是一种武器,而真正运用武器的高手是没有武器胜有武器。只有根据实际的需要,凭借一定的思想,才能实现符合实际的重构,我们不能被一些固定的模式套牢了,这样你的程序会很僵化。究竟如何把握这个度,需要大家去总结。,重构与思想,要想实现一个好的重构,不是重构本身,而是我们在写代码的时候,思想当中时刻有它的位置存在!非常重要!如果你本身就没想着要去重构,那么就是有再好的模式供你调用又怎么样?就是有了好的模式,你不能根据实际的需要去融会贯通,那你做出来的重构有意义么?,应用范围,代码重构 网页重构 设计重构 .,Refactoring的流程,流程1 读懂代码(包括测试例子代码) Refactoring 运行所有的Unit Tests 流程2 读懂代码 应用重构工具进行重构(如Eclipse),代码坏味道,重复的代码(Duplicated Code) 过长的函数(Long Method) 过大类(Large Class) 过长的参数列(Long Parameter List) 发散式变化(Divergent Change) 霰弹式修改(Shotgun Surgery) 依恋情结(Feature Envy) 数据泥团(Data Clumps) 基本型别偏执(Primitive Obsession) Switch语句(Swtich Statements) 平行继承体系(Parallel Inheritance Hierarchies) 冗赘类(Lazy Class),夸夸其谈未来性(Speculative Generality) 令人迷惑的暂时值域(Temporary Field) 过度遇合的消息链(Message Chains) 中间转手人(Middle Man) 狎昵关系(Inappropriate Intimacy) 异曲同工的类(Alternative Classes with Different Interfaces) 不完善的程序库类(Incomplete Library Class) 纯粹的数据类(Data Class) 被拒绝的遗赠(Refused Bequest) 过多的注释(Comments),重构技巧,重新组织你的函数 在对象之间搬移特性 重新组织数据 简化条件表达式 简化函数调用 处理概括关系,Extract Methods(提炼函数1),String name = request.getParameter(“Name“); if( name != null if( age != null & age.length() 0 ),String name = request.getParameter(“Name“); if( !isNullOrEmpty( name ) ) String age = request.getParameter(“Age“); if( !isNullOrEmpty( age ) )private boolean isNullOrEmpty( final String string ) if( string != null ,Extract Methods(提炼函数:清除注释),void printOwing() /print banner System.out.println(“*”); System.out.println(“Banner”); System.out.println(“*”); /print details System.out.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.out.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 basePrice() * 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 something ,if ( (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 + _width); 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 result;if (_isDead) result = deadAmount();else if (_isSeparated) result = separatedAmount();else if (_isRetired) result = retiredAmount();else result = normalPayAmount();return result; ;,
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号