refactoring with eclipse - uvic.cawebhome.cs.uvic.ca/~hausi/seng371/labs/seng371-bassam-lab8-… ·...
TRANSCRIPT
Refactoring with Eclipse Seng 371 Lab 8
By Bassam Sayed
Based on IBM article “Explore refactoring functions in Eclipse JDT“ by Prashant Deva
Code Refactoring � Code refactoring is a disciplined way to restructure
code. [wikipedia]
� Refactoring process consists of a series of “refactorings” each of which is (usually) a tiny change in the source code that doesn’t modify its functional requirements. [wikipedia]
� Usually refactoring is motivated by noticing a code problem (smell). For example, very long functions or a near duplicate of another method.
Refactoring Benefits � Maintainability: It is easier to fix bugs when the source
code is easy to read and understand.
� 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 [Kerievsky, Joshua (2004). Refactoring to Patterns]
� It is recommended that before starting the refactoring process a set of unit tests get performed on the source code to demonstrate the correctness of the module. Then this process is repeated with every small change.
Refactoring Techniques � Some examples of refactoring techniques:
� Techniques that allow for more abstraction such as Field Encapsulation (forcing the code to access the fields with setters and getters)
� Techniques for breaking code apart into more logical pieces such as extracting methods and extracting classes.
� Techniques for improving names and location of code such as moving methods and fields, renaming methods and fields. Pull Up and Push Down in OOP programming.
Refactoring Types in Eclipse JDT
� Rename: It allows renaming of variables, classes, methods, packages, folders, and almost any Java identifiers. When you rename an identifier, all references to that identifier are also renamed. Shortcut Alt+Shift+R.
� Move: You can use Move to move a class from one package to another. It physically moves the class to the folder corresponding to the package and also changes all references to the class to refer to the new package. You can drag and drop a class to a new package in the Package Explorer view, and the refactoring will take place automatically.
Refactoring Types in Eclipse JDT (Cont.)
� Extract Local Variable: Allows assigning the result of a java expression to a new local variable. Useful when writing a complex expression by quickly dividing it into multiple lines. To use it press Ctrl+1 and select assign statement to a local variable.
� Convert local variable to field: takes a local variable and converts it to a private field of the class. All references to the local variable after this refer to the field. To use it press Ctrl+1 and select convert local variable to field
Refactoring Types in Eclipse JDT (Cont.)
� Convert Anonymous Class to Nested: takes an anonymous class and converts it to a nested class of the method that originally contained the anonymous class. To use select Refactor > Convert Anonymous Class to Nested while the cursor is inside the anonymous class.
Convert Anonymous Class to Nested Example
void createPool() { threadPool = Executors.newFixedThreadPool(1, new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName("Worker thread"); t.setPriority(Thread.MIN_PRIORITY); t.setDaemon(true); return t; } });
}
Convert Anonymous Class to Nested Example
private final class MyThreadFactory implements ThreadFactory{ @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName("Worker thread"); t.setPriority(Thread.MIN_PRIORITY); t.setDaemon(true); return t; } }
void createPool(){ threadPool = Executors.newFixedThreadPool(1, new MyThreadFactory());
}
Refactoring Types in Eclipse JDT (Cont.)
� Convert Member Type to Top Level: takes a nested class and converts it to a top-level class with its own Java file. To use place cursor inside the nested class and select Refactor > Convert Member Type to Top Level. � If the nested class is a static class, a box showing a
preview of the refactoring displays right away. If it is not a static class, you first need to declare the name of the field that will hold the reference to the parent class of the nested class before you get to the preview box.
Refactoring Types in Eclipse JDT (Cont.)
� Extract Interface: makes an interface out of the methods defined in a class. � To use this refactoring, select Refactor > Extract
Interface from the menu. A dialog box displays, requesting the name of the new interface. You can check the methods from the class that will be declared in the interface.
Refactoring Types in Eclipse JDT (Cont.)
� Extract Superclass: It is similar to the Extract Interface refactoring described earlier. However, the Extract Superclass extracts a superclass instead of an interface. If the class already uses a superclass, the newly generated superclass will have that class as its superclass, maintaining the class hierarchy. � To use this refactoring, make sure your cursor is on one of
the method declarations or fields of the class and select Refactor > Extract Superclass.
� A huge difference between extracting a superclass and extracting an interface is that the methods put in the superclass are actually moved there. So, if any of those methods contain references to any fields in the original class, you get a compiler error.
Refactoring Types in Eclipse JDT (Cont.)
� Extract Method: The Extract Method refactoring allows you to select a block of code and convert it to a method. Eclipse automatically infers the method arguments and return types. � This is useful when a method is too big and you want
to subdivide blocks of it into different methods.
� It is also useful if you have a piece of code that is reused across many methods. When you select one of those blocks of code and do a refactoring, Eclipse finds other occurrences of that block of code and replaces it with a call to the new method.
Refactoring Types in Eclipse JDT (Cont.)
� Extract Method: To use this refactoring, select a block of code in the editor and press Alt+Shift+M. A dialog box displays, requesting the name and visibility (public, private, protected, or default) of the new method. You can even change the parameters and return types.
Extract Method Example public Object get(Object key) {
TimedKey timedKey = new TimedKey(System.currentTimeMillis(), key); Object object = map.get(timedKey);
if (object != null) { /** * if this was removed after the 'get' call by the worker thread * put it back in */ map.put(timedKey, object); return object; }
return null;
}
Extract Method Example public Object get(Object key) {
TimedKey timedKey = new TimedKey(System.currentTimeMillis(), key); Object object = map.get(timedKey);
return putIfNotNull(timedKey, object);
} private Object putIfNotNull(TimedKey timedKey, Object object) {
if (object != null) { /** * if this was removed after the 'get' call by the worker thread * put it back in */ map.put(timedKey, object); return object; }
return null;
}
Refactoring Types in Eclipse JDT (Cont.)
� Inline: The Inline refactoring can inline a reference to a variable or method. When used, it replaces the reference to the variable or method with the value assigned to the variable or the implementation of the method, respectively. This can be useful for cleaning up your code in the following situations: � When a method is called only once by another
method, and it makes more sense as a block of code. � When an expression looks cleaner on one line, rather
than split into multiple lines by assigning values to different variables.
Inline Example //Before Inline refactoring public Object put(Object key, Object value)
{ TimedKey timedKey = new TimedKey(System.currentTimeMillis(), key); return map.put(timedKey, value); }
//After Inline refactoring public Object put(Object key, Object value)
{ return map.put(new TimedKey(System.currentTimeMillis(), key), value); }
Refactoring Types in Eclipse JDT (Cont.)
� Change Method Signature: The Change Method Signature refactoring allows you to change the signature of a method. It modifies all calls to that method to use the new signature. � To use this refactoring, select Refactor > Change
Method Signature. The dialog box shown in the next Figure, allowing you to change everything about the method, including adding or removing parameters, changing the order of the parameters, changing the return value type, adding exceptions to the declaration of the method, and even changing the name of the method.
Refactoring Types in Eclipse JDT (Cont.)
� Infer Generic Type Arguments: The Infer Generic Type Arguments refactoring automatically tries to guess the appropriate generic types for classes used in their raw form. This refactoring is generally used to convert pre-Java 5 code to Java 5 and later code. � This refactoring can even be invoked from the
Package Explorer. Simply right-click on any project, package, or class in the Package Explorer and select Refactor > Infer Generic Type Arguments.
Infer Generic Type Arguments Example
//Before refactoring private final ConcurrentHashMap map = new ConcurrentHashMap(); //After refactoring private final ConcurrentHashMap<TimedKey, Object> map = new ConcurrentHashMap<TimedKey, Object>();
Refactoring Types in Eclipse JDT (Cont.)
� Migrate JAR File: The Migrate JAR File refactoring allows you to easily upgrade Java Archive (JAR) files on a project's build path. � The Migrate JAR File refactoring allows you to do this in
one step. To invoke the refactoring, select Refactor > Migrate Jars. In the dialog box that displays, select the location of the new JAR file. In the tree below, select the JAR from the project that will be upgraded to the new version. If you select the Replace Jar file contents but preserve existing filename checkbox, the new JAR file is renamed to match the name of the old JAR file, thus not breaking any build scripts that refer to the JAR file by that name. In any case, when you click Finish, the previous JAR file is deleted, and the new JAR file is copied to its location and automatically added to the project's build path, making your project use the new JAR file.
Refactoring Types in Eclipse JDT (Cont.)
� Refactoring scripts: Refactoring scripts allow you to export and share refactoring actions. This is extremely useful when you are about to distribute a new version of a library that can cause errors for people using the older version. � To create a refactoring script, go to Refactor > Create
Script. The window shown in the next Figure, showing the history of all the refactorings that have been performed in the workspace. Select the ones you need, specify a location for the script to be generated, then click Create to generate the script.
Refactoring Types in Eclipse JDT (Cont.)
� Refactoring Script: To apply an existing refactoring script to your workspace, select Refactor > Apply Script. In the dialog box that displays, select the location of the script. Click Next to see the refactorings that this script will perform, then click Finish to apply the refactorings.