240 likes | 718 Views
Refactoring. Refactoring. :: What is it?. Definition: Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior .
E N D
Refactoring Refactoring
Refactoring :: What is it? Definition: Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior. Refactoring does not fix bugs, but it may help find bugs by scrutinizing code. It may also reduce further bugs occurrence by cleaning-up code. Refactoring does not add new functionality to the system, but it will ease the further adding of new functionality. Refactoring
Refactoring :: when? Refactoring ought to be done continuously as “bad smells” are encountered during programming. More importantly, when using iterative development, a major refactoring stage should precede the beginning of the development of a new build. This will remove slight design problems and ease the addition of further functionality. In this case, refactoring counterbalances the productivity-driven software development practices implied by agile incremental software development. Refactoring
Refactoring :: why? Refactoring is usually done to: improve code readability & comprehensibility simplify code structure, improve design quality improve maintainability improve extensibility • Improve some of the nonfunctional attributes of the software • Does not modify its functional requirements Refactoring
There are two general categories of benefits to the activity of refactoring. • Maintainability. It is easier to fix bugs because the source code is easy to read and the intent of its author is easy to grasp.This might be achieved by reducing large monolithic routines into a set of individually concise, well-named, single-purpose methods. It might be achieved by moving a method to a more appropriate class, or by removing misleading comments. • Extensibility. It is easier to extend the capabilities of the application if it uses recognizable design patterns, and it provides some flexibility where none before may have existed. Refactoring
Before refactoring a section of code, a solid set of automatic unit tests is needed. The tests should demonstrate in a few seconds that the behavior of the module is correct. The process is then an iterative cycle of making a small program transformation, testing it to ensure correctness, and making another small transformation. If at any point a test fails, you undo your last small change and try again in a different way. Through many small steps the program moves from where it was to where you want it to be. Proponents of extreme programming and other agile methodologies describe this activity as an integral part of the software development cycle Refactoring
Refactoring :: how is it done? Each refactoring is implemented as a small behavior-preserving transformation. Behavior-preservation is achieved through pre- and post-transformation testing. Refactoring process: test-refactor-test Refactoring
Refactoring :: drawbacks Cost Overhead: Refactoring is an add-on activity and therefore will incur extra cost in form of time, effort, and resource allocation, especially if elaborated design and code documentation is maintained. However, when done sparingly and only on key issues, its benefits are greater than its overhead. Automated documentation tools will also diminish the overhead. Requires Expertise: Refactoring requires some expertise and experience and considerable effort in going through the process, especially if proper testing is involved. However, this overhead can be minimized by using automated testing such as with a unit testing framework. Refactoring
Refactoring :: examples Encapsulate Downcast: A method returns an object that needs to be downcasted by its callers. Refactor by moving the downcast to within the method. Object lastReading() { return readings.lastElement(); } Reading lastReading() { return (Reading) readings.lastElement(); } Refactoring
Refactoring :: examples Consolidate Conditional Expression: You have a sequence of conditional tests with the same result. Refactor by combining them into a single conditional expression and extract it. double disabilityAmount() { if (_seniority < 2) return 0; if (_monthsDisabled > 12) return 0; if (_isPartTime) return 0; // compute the disability amount double disabilityAmount() { if (isNotEligibleForDisability()) return 0; // compute the disability amount Refactoring
Refactoring :: examples Consolidate Duplicate Conditional Fragments: The same fragment of code is in all branches of a conditional expression. Refactor by moving it outside of the expression. if (isSpecialDeal()) { total = price * 0.95; send(); } else { total = price * 0.98; send(); } if (isSpecialDeal()) total = price * 0.95; else total = price * 0.98; send(); Refactoring
Refactoring :: examples Rename Method: The name of a method does not reveal its purpose. Refactor it by changing the name of the method. int getInvCdtLmt(){ … } int getInvoiceableCreditLimit(){ … } Refactoring
Refactoring :: examples Pull Up Field: Two subclasses have the same field. Refactor it by moving the field to the superclass. Refactoring
Refactoring :: examples Push Down Method: Behavior on a superclass is relevant only for some of its subclasses. Refactor it by moving it to those subclasses. Refactoring
Refactoring :: practice • Some refactorings are controversial. • Some refactorings are arguably not improving code quality. • Some refactorings can in fact be counter-productive when applied blindly, especially in iterative development, where design is evolving. Have your team adopt a set of refactorings to be applied, and make sure that refactorings are applied in a productive manner. Apply in combination with the application of design patterns. Use refactoring tools to automate changes, e.g. Eclipse Refactoring
Refactoring is the process of applying behavior-preserving transformations to a program with the objective of improving the program's design. A specific refactoring is identified by a name (e.g., Extract Method), a set of preconditions, and a set of specific transformations that need to be performed. Tool support for refactoring is highly desirable because checking the preconditions for a given refactoring often requires nontrivial program analysis, and applying the transformations may affect many locations throughout a program. In recent years, the emergence of light-weight programming methodologies such as Extreme Programming has generated a great amount of interest in refactoring, and refactoring support has become a required feature in modern-day IDEs. Refactoring
Automated Code Refactoring • Many software editors and IDEs have automated refactoring support. Here is a list of a few of these editors, or so-called refactoring browsers. • IntelliJ IDEA (for Java) • Eclipse's Java Development Toolkit (JDT) • NetBeans (for Java) • and RefactoringNG, a Netbeans module for refactoring where you can write transformations rules of the program's abstract syntax tree. • Embarcadero Delphi • Visual Studio (for .NET) • JustCode (addon for Visual Studio) • ReSharper (addon for Visual Studio) Refactoring
Automated Code Refactoring Coderush (addon for Visual Studio) Visual Assist (addon for Visual Studio with refactoring support for VB, VB.NET. C# and C++) DMS Software Reengineering Toolkit (Implements large-scale refactoring for C, C++, C#, COBOL, Java, PHP and other languages) Photran a Fortran plugin for the Eclipse IDE SharpSort addin for Visual Studio 2008 Sigasi HDT (for VHDL) XCode Smalltalk Refactoring Browser (for Smalltalk) Simplifide (for Verilog, VHDL and SystemVerilog) Tidier (for Erlang) Refactoring
To refactor code in eclipse or IDEA, you select the code you want to refactor, pull down the specific refactoring you need from a menu, and the IDE does the rest of the hard work. You are prompted appropriately by dialog boxes for new names for things that need naming, and for similar input. You can then immediately rerun your tests to make sure that the change didn't break anything. If anything was broken, you can easily undo the refactoring and investigate. Refactoring
Types of Refactoring in Eclipse Refactoring
Example The Rename refactoring does just that, it renames a Java element. Although you can rename Java files and Java elements by hand, this will not update any references to those files and elements. You should have to search through the files in your project and replace the appropriate references by hand. This is always the chance that you might miss a reference or replace a wrong reference. The Rename refactoring will intelligently update all of the appropriate references in a project for you. Refactoring
Example Applying some refactoring that modify the structure of classes such as Push Down and Pull Up may not modify the other classes in a project. In this case you will have to make sure that all references to the modified elements are updated. This is why a good test suites is needed, although you may have to update references in the test classes as well. An example of this is using the Push Down refactoring on a method. If another class has an instance of the class that originally had the method and makes a class to the method, after the Push Down refactoring there will be an error in the calling class because the method is no longer found in the original class. Refactoring
Resources Catalog of Refactorings. http://www.refactoring.com/catalog/index.html Refactoring Home Page. http://www.refactoring.com/ Martin Fowler. Refactoring: Improving the Design of Existing Code, Addison-Wesley, 1999. ISBN 0-201-48567-2. Kerievsky, Joshua. Refactoring To Patterns. Addison- Wesley, 2004. ISBN 0-321-21335-1. Wake, William C.. Refactoring Workbook. Addison-Wesley, 2003. ISBN 0-321-10929-5. Refactoring