网站页面建设规划文案,室内设计有哪些网站,网址大全下载app,在线制作图标What Refacing#xff1a; 重构#xff08;Refactoring#xff09;就是在不改变软件现有功能的基础上#xff0c;通过调整程序代码改善软件的质量、性能#xff0c;使其程序的设计模式和架构更趋合理#xff0c;提高软件的扩展性和维护性。 经典的Refacing Definition 重构Refactoring就是在不改变软件现有功能的基础上通过调整程序代码改善软件的质量、性能使其程序的设计模式和架构更趋合理提高软件的扩展性和维护性。 经典的Refacing Definition 1Refactoring means rewriting existing source code with the intent of improving its design rather than changing its external behavior. The focus of refactoring is on the structure of the source code, changing the design to make the code easier to understand, maintain, and modify. 来自Borland Together提供的文档觉得这个定义很清晰明了。 2重构是这样一个过程在不改变代码外在行为的前提下对代码做出修改已改进程序的内部结构。来自Martin Fowler的定义。 Refactoring (noun): a change made to the internal structure of software to make iteasier to understand andcheaper to modifywithout changing its observable behavior. Refactor (verb): to restructure softwareby applying a series of refactoringswithout changing its observable behavior. Why Refacing Improves the design of software Makes software easier to understand - leads to higher levels of understanding Helps to find bugs Helps to be more effective at writing robust code Helps to program faster 1、·持续偏纠和改进软件设计。 2、·使代码更易为人所理解。 3、·帮助发现隐藏的代码缺陷。 4、·从长远来看有助于提高编程效率。 When RefacingThree strikes and you refactor. When you add functionality. When you need to fix a bug. When you do a code review. 1、·代码中存在重复的代码。 2、·过大的类和过长的方法。 3、·牵一毛而需要动全身的修改。 4、·类之间需要过多的通讯。 5、·过度耦合的信息链。 6、·不完美的设计。 7、·缺少必要的注释。 不要当你需要新的功能的时候或者原来的程序出了Bug你才想起重构。 总结代码重构在你开始写代码就是被要考虑进去的边写代码边重构。 What makes programs hard to work with? Kent Beck: We want programs:easy to read,have all logic specified in one and only place,do not allow changes to endanger existing behavior,allow conditional logic to be expressed as simply as possible. Refactoring and Design Refactoring and Performance Refactoring will make software run more slowly, but it also makes the software more easy for performance tuning. The secret to fast software is towrite tunable software first andthen to tune it for sufficient speed. Run a profiler to find the performance hot spots. Focus on these performance hot spots and optimize them. Rerun the profiler, if the performance does not improve, back out the change. Continue the process until the performance satisfies your users. How Refacing 减少代码坏味道Bad Smell in Codes的重构策略 1Duplicated Code 尽量消除重复的代码将它们合而为一 Do Not Repeat Yourself. 根据重复的代码出现在不同的地方分别采取不同的重构的策略 在同一个Class的不同地方通过采用重构工具提供的Extract Method功能提炼出重复的代码 然后在这些地方调用上述提炼出方法。 在不同Subclasses中通过Extract Method提炼出重复的代码然后通过Pull Up Method将该方法移动到上级的Super class内。 在没有关系的Classes中通过对其中一个使用Extract Class将重复的代码提炼到一个新类中然后在另一个Class中调用生成的新类消除重复的代码。 2Long Method 拆解过长的函数 过长的函数在我们的日常代码中经常可见在C#中常通过#region #endregion区隔为不同的功能区域。 重构策略通过Extract Method将过长的函数按照功能的不同进行适当拆解为小的函数并且给这些小函数一个好名字。通过名字来了解函数提供的功能提高代码的理解性。 3Large Class 拆解过大的类 过大的类也经常见到特别是类中含有大量的成员变量。 重构策略通过Extract Class将一些相关成员变量移植到新的Class中如Employee类一般会包含有联系方式的相关属性电话 Mobile地址Zip等等则可以将这些移植到新的EmployeeContact类中。 4Long Parameter List 过长的参数列 过长的参数列的主要问题是难以理解并且难以维护。如果要增加新的参数或者删除某一参数易造成参数前后不一致。 重构策略如果可以通过向已存在的对象查询获取参数则可通过Replace Parameter with Method移除参数列通过在函数内部向上述已存在的对象查询来获取参数。 如果参数列中若干参数是已存在对象的属性则可通过Preserve Whole Object将这些参赛替换为一个完整对象这样不仅提高代码的可读性同时已易于代码今后的维护。 另外还可以将若干不相关的参数使用Introduce Parameter Object来创建一个新的参数类。不过我个人觉得如果这些情况过多的话会产生很多莫名其妙的参数类了反而降低代码的可读性。 5Divergent Change发散式变化 现象当某个Class因为外部条件的变化或者客户提出新的功能要求等时每次修改要求我们更新Class中不同的方法。不过这种情况只有在事后才能觉察到因为修改都是在事后发生的么废话。 重构策略将每次因同一条件变化而需要同时修改的若干方法通过Extract Class将它们提炼到一个新Class中。实现目标是每次变化需要修改的方法都在单一的Class中并且这个新的Class内所有的方法都应该与这个变化相关。 6Shotgun Surgery霰弹式修改 现象当外部条件发生变化时每次需要修改多个Class来适应这些变化影响到很多地方。就像霰弹一样发散到多个地方。 重构策略使用Move Method和Move Field将Class中需要修改的方法及成员变量移植到同一个Class中。如果没有合适的Class则创建一个新Class。实现目标是将需要修改的地方集中到一个Class中进行处理。 比较Divergent Change发散式变化和Shotgun Surgery霰弹式修改 前者指一个Class受到多种外部变化的影响。而后者指一种变化需要影响到多个Class需要修改。都是需要修理的对象。 7Feature Envy依恋情结 现象Class中某些方法“身在曹营心在汉”没有安心使用Class中的成员变量而需要大量访问另外Class中的成员变量。这样就违反了对象技术的基本定义将数据和操作行为方法包装在一起。 重构策略使用Move Method将这些方法移动到对应的Class中以化解其“相思之苦”让其牵手。 8Data Clumps数据泥团 现象指一些相同数据项目Data Items如Class成员变量和方法中参数列表等在多个Class中多次出现并且这些数据项目有其内在的联系。 重构策略通过使用Introduce Parameter Object创建新的参数对象取代这些参数或Preserve Whole Object使用已存在的对象取代这些参数实现使用对象代替Class成员变量和方法中参数列表清除数据泥团使代码简洁也提高维护性和易读性。 9Primitive Obsession基本型偏执狂 现象在Class中看到大量的基本型数据项目Data Item如Employee类中有大量的数据成员Employee#, FirstName, MiddleName, LastName, Address, State, City, Street, Zip, OfficePhone, CellPhone, Email……等等。 重构策略使用Extract Class提炼新类或Preserve Whole Object使用已存在的对象取代这些参数实现使用对象代替基本型数据项目Data Item。如上述Employee类中就可分别提炼出EmployeeName和EmployeeContact两个新类。 10Switch StatementsSwitch语句 现象同样的Switch语句出现在不同的方法或不同的Class中这样当需要增加新的CASE分支或者修改CASE分支内语句时就必须找到所有的地方然后进行修改。这样就比较麻烦了。 重构策略(1)首先采用Extract Method将Switch语句提炼到一个独立的函数。 (2)然后以Move Method搬移到需要多态性Polymorphism的Superclass里面或者是构建一个新的Superclass。 (3)进一步使用Replace Type Code with Subclasses或者Replace Type Code with State/Strategy。这步就比较麻烦些不过记住如下基本规则这里一般有3个Class分别为Source Class、Superclass和Subclass。 Source Class l 使用Self Encapsulate Field将Type Code成员变量封装起来也就是建立对应的Setter/Getter函数。 l 在Source Class中增加一个Superclass类型的成员变量用来存放Subclass实例对象。 l 在Source Class中的Getter函数通过调用Superclass的Abstract Query函数来完成。 l 在Source Class中的Setter函数通过调用Superclass中的Static工厂化方法来获取合适的Subclass实例对象。 Superclass 新建的一个Class注就是上面通过Move Method搬移生成的Superclass根据Type Code的用途命名该Class作为Superclass。 l 在Superclass中建立一个Abstract Query函数用来获取Subclass的Type Code。 l 在Superclass中创建Static工厂化方法生产对应的Subclass对象这里会存在一个Switch语句不要再动脑筋来重构这个Switch语句了这个Switch语句不会在多处重复存在并且这里用于决定创建何种Subclass对象这是完全可以接受的。 Subclass l 根据每一个Switch/Type分支建立对应的Subclass并且Subclass的命名可以参考Switch/Type分支的命名。 l 在每一个Subclass中重载Superclass的Abstract Query函数返回特定的Type Code。 (4)现在Superclass仍然存在Switch分支是时候轮到Replace Conditional with Polymorphism上场了。具体而言就是在每一个Subclass中创建重载方法注该方法是Superclass中含有Switch语句的方法并将Superclass中Switch语句对应的Case分支剪切过来。最后将Superclass中该方法初象化Abstract并清除Switch语句及其所有的Case分支。 这样就完成了整个重构过程这个比较麻烦。 11Parallel Inheritance Hierarchies平行继承体系 现象为某个class增加一个subclass时也必须为另一个class相应增加一个subclass。重构策略 在一个class继承体系的对象中引用refer to另一个class继承体系的对象然后运用Move Method和Move Field将被引用class中的一些方法和成员变量迁移宿主class中消除被引用class的继承体系注这种平行继承体系好象比较少见也。 12Lazy Class冗赘类 现象某一些class由于种种原因现在已经不再承担足够责任有些多余了。如同国有企业冗余人员一样需要下岗了。 重构策略通过Collapse Hierarchy将这些冗余的class合并到superclass或subclass中或者通过Inline Class与Extract Class相反将这些冗余class中的所有Method/Field迁移到其他相关的class中。 13Speculative Generality夸夸其谈未来性 现象系统中出现一些无用的abstract class或者非必要的delegation委托或者多余的参数等等。 重构策略分别使用Collapse Hierarchy合并abstract class使用Inline Class移除非必要的delegation使用Remove Parameter删除多余的参数。 14Temporary Field令人迷惑的暂时值域 现象class中存在一些Field这些Field只在某种非常特定的情况下需要。 重构策略通过Extract Class将这些孤独的Field及其相关的Method移植的一些新的Class中。提炼出来的新Class可能没有任何抽象意义只是提供Method的调用这些新Class一般称为Method Object。 15Message Chains过度耦合的消息链 现象向一个对象请求另一个对象然后再向后者请求另一个对象……这就是Message Chain意味着Message Chain中任何改变将导致Client端不得不修改。 重构策略通过Hide Delegate隐藏委托关系消除Message Chain具体做法是在Message Chain的任何地方通过Extract Method建立一个简单委托Delegation函数来减少耦合Coupling。 16Middle Man中间转手人 现象过度运用delegation某个/某些Class接口有一半的函数都委托给其他class这样就是过度delegation。 重构策略运用Remove Middle Man移除简单的委托动作也就是移除委托函数让client直接调用delegate受托对象。和上面的Hide Delegate隐藏委托关系刚好相反的过程。 由于系统在不断的变化和调整因此[合适的隐藏程度]这个尺度也在相应的变化Hide Delegate和Remove Middle Man重构策略可以系统适应这种变化。 另外可保留一部分委托关系delegation同时也让Client也直接使用delegate受托对象。 17Inappropriate Intimacy狎昵关系 现象两个Class过分亲密彼此总是希望了解对方的private成分。 重构策略可以采用Move Method和Move Field来帮助他们划清界限减少他们之间亲密行为。或者运用Change Bidirectional Association to Unidirectional将双向关联改为单向降低Class之间过多的依存性inter-dependencies。或者通过Extract Class将两个Class之间的共同点移植到一个新的Class中。 18Alternative Classes with Different Interfaces异曲同工的类 现象两个函数做相同的事情却有不同的signature。 重构策略使用Rename Method根据他们的用途来重命名。另外可以适当运用Move Method迁移某些行为使Classes的接口保持一致。 19Incomplete Library Class不完美的程序库类 现象Library Class类库设计不是很完美我们需要添加额外的方法。 重构策略如果可以修改Library Class的Source Code直接修改最好。如果无法直接修改Library Class并且只想修改Library Class内的一两个函数可以采用Introduce Foreign Method策略在Client Class中建立一个函数以外加函数的方式来实现一项新功能一般而言以server class实例作为该函数的第一个参数。 如果需要建立大量的额外函数可应该采用Introduce Local Extension建立一个新class使它包含额外函数并且这个class或者继承或者wrap包装source class。 20Data Class纯稚的数据类 现象Data Class指一些Class拥有Fields以及用来访问Fields的getter/setter函数但是没有其他的功能函数。感觉这些Data Class如同Entity Class或Parameter Class用来传递参数我认为这种情况下没有必要重构。 重构策略找出其他class中访问Data Class中的getter/setter的函数尝试以Move Method将这些函数移植到Data Class中实现将数据和操作行为方法包装在一起也让Data Class承担一定的责任方法。 21Refused Bequest被拒绝的遗赠 现象Subclass不想或不需要继承superclass的部分函数和Field。 重构策略为subclass新建一个兄弟sibling class再运用Push Down Method和Push Down Field将superclass中的相应函数和Field下推到兄弟class这样superclass就只包含subclass共享的东西了。其实也就是将superclass中一些与特定的函数和Field放到特定的subclass中superclass中仅包含subclass共享的函数和Field。 如果不想修改superclass还可以运用Replace Inheritance with Delegation来达到目的。也就是以委托取代继承在subclass中新建一个Field来保存superclass对象去除subclass对superclass的继承关系委托或调用superclass的方法来完成目的。 22Comments过多的注释 现象晕倒这个也要重构Remove掉所有的Comments吗不是。当代码中出现一段长长的注释一般是由于代码比较糟糕需要进行重构除去代码的坏味道。 重构策略通过上面提及的各种重构策略将代码的坏味道去除使注释变成多余。 如果需要注释/解释一段代码做了什么则可以试试Extract Method提取出一个独立的函数让函数名称解释该函数的用途/功能。另外如果觉得需要注释来说明系统的某些假设条件 也可尝试使用Introduce Assertion引入断言来明确标明这些假设。 当你感觉需要撰写注释时请先尝试重构试着让所有的注释都变得多余。 注并不是一看到Switch语句及CASE分支就马上/偏执狂采用上述重构策略进行重构画蛇添足或吃亏不讨好个人观点。一般而言只有看到多处出现相同的Switch语句时才应该考虑进行重构。 Refactoring Practice 1、When you find you have to add a feature to a program, and the programs code is not structured in a convenient way to add the feature, first refactor the program to make it easy to add the feature, then add the feature. 2、Before you start refactoring, check that you have a solid suite of tests. These tests must be self-checking. 3、Refactoring changes the programs in small steps. If you make a mistake, it is easy to find the bug. 4、Any fool can write code that a computer can understand. Good programmers write code that humans can understand. 5、Dont publish interfaces prematurely. Modify your code ownership policies to smooth refactoring. 6、Make sure all tests are fully automatic and that they check their own results. 7、A suite of tests is a powerful bug detector that decapitates the time it takes to find bugs. 8、Run your tests frequently. Localize tests whenever you compile—every test at least every day. 9、When you get a bug report, start by writing a unit test that exposes the bug. 10、It is better to write and run incomplete tests than not to run complete tests. 11、Think of the boundary conditions under which things might go wrong and concentrate your tests there. 12、Dont forget to test that exceptions are raised when things are expected to go wrong. 13、Dont let the fear that testing cant catch all bugs stop you from writing the tests that will catch most bugs. 1、把握全局先了解业务 2、阅读代码清除冗余代码重构变量名等删除不一致或无效的注释补写注释为下一步做准备 3、将通用的代码块提升为方法 4、小步前进随时测试 5、重构要随时进行 6、避免过度设计。模式是把双刃剑。 最终的收获每个程序员都应该不断加强自己的编程思想注重编程质量。 How Bad Smell in Codes1、 管理层不重视代码书写认为是体力劳动 2、 项目经理疲于应付进度无心且无力 3、 程序员水平参差不齐缺乏正确的指导。 4、.经验不足分析设计不到位 5、.敏捷开发虽然经验很多但为了快速开发没有经过分析设计 6、.缺乏意识只为实现功能而写代码不管代码质量 About Refacing 重构工作虽然重要但是得不到过多的认可目前国内关注的是可用性对于代码质量并没有得到应有的重视。 Refacing Books 《work effectively with legacy code》 修改代码的艺术 《The Programtic Programmer From JoumeyMan to Master》 程序员修炼之道 《Pattern-Oriented Software Architecture Volume 4》 面向模式的软件架构 卷4 《Agile Principles、Patterns and Practice in C#》 敏捷软件开发 原则、模式与实践C#版 《Code Quality The Open Source Perspective》 高质量程序设计艺术 《Refactoring improving the Designe of Existing Code》 重构 改善既有代码的设计 《Design Patterns Explained 》 设计模式解析 《反模式 危机中软件、架构和项目的重构》 《Refactoring to Patterns》 重构与模式 《More Programming Pearls》 编程珠玑II 《Programming Pearls》 编程珠玑第2版 《Beginning Java Objects》 中文版从概念到代码第2版 《设计模式解析第2版》 《敏捷软件开发原则、模式与实践C#版》 《Java设计模式》 《重构与模式》 《UML面向对象建模与设计第2版》 转载于:https://www.cnblogs.com/yefengmeander/archive/2011/08/18/2887695.html