CSC/ECE 517 Fall 2011/ch5 5d he: Difference between revisions
(55 intermediate revisions by 2 users not shown) | |||
Line 5: | Line 5: | ||
==Introduction== | ==Introduction== | ||
Refactoring is a technique for restructuring an existing code, altering its internal structure without changing its external behavior. Its done as a series of small transformations. Each transformation does little, but a sequence of transformations can produce a significant restructuring. Since each refactoring is small, it's less likely to go wrong. The system is also kept fully working after each small refactoring, reducing the chances that a system can get seriously broken during the restructuring.<ref name="refone"> Refactoring Home Page http://refactoring.com/ </ref> As people make changes to the code to realize their short term goals without fully understanding the design of code, the code loses its structure. The refactoring work is done to remove bits that aren’t really in the right place. Loss of the structure of code has a cumulative effect. The harder it is to see the design in the code, the harder it is to preserve it, and the more rapidly it decays. Regular refactoring helps code retain its shape. <ref name="reftwo"> Why should you Refactor http://sourcemaking.com/refactoring/why-should-you-refactor </ref> | Refactoring is a technique for restructuring an existing code, altering its internal structure without changing its external behavior. Its done as a series of small transformations. Each transformation does little, but a sequence of transformations can produce a significant restructuring. Since each refactoring is small, it's less likely to go wrong. The system is also kept fully working after each small refactoring, reducing the chances that a system can get seriously broken during the restructuring.<ref name="refone"> Refactoring Home Page http://refactoring.com/ </ref> As people make changes to the code to realize their short term goals without fully understanding the design of code, the code loses its structure. The refactoring work is done to remove bits that aren’t really in the right place. Loss of the structure of code has a cumulative effect. The harder it is to see the design in the code, the harder it is to preserve it, and the more rapidly it decays. Regular refactoring helps code retain its shape. <ref name="reftwo"> Why should you Refactor http://sourcemaking.com/refactoring/why-should-you-refactor </ref> | ||
<p> | |||
Fully autonomous factoring doesn't appear to exist at this time in the IDE(s) described below. However there are papers <i>Inducing Evolution-Robust Pointcuts</i> <Ref name="refseven">Inducing Evolution-Robust Pointcuts, Braem, M.</ref> and <i>Automatic Refactoring of Erlang Programs</i><ref name="refeight">Automatic Refactoring of Erlang Programs http://www.ece.cmu.edu/~aavgerin/papers/PPDP09.pdf</ref> that point the way to the future of refactoring that can be fully automated. In the context of this wiki article, automatic refactoring means automated refactoring under programmer control and guidance. | |||
</p> | |||
==Common Refactoring Techniques== | |||
===Extraction Refactoring=== | |||
There are several refactoring techniques related to extraction: Extract method, Extract local variables, extract constants. The first method "Extract method will create a new method from code you've selected. Extract Local Variable refactoring takes an expression that is being used repeatedly and assigns it to a local variable. Extract constant refactoring is to select a static, constant expression, which the refactoring will convert to a static final constant. This is useful for removing hard-coded numbers and strings from your code | |||
===Inline Refactoring=== | |||
This type refactoring is the reverse of local variable extraction, in which we remove a local variable and use the value of the variable(typically an expression) in the place where the variable is used. This can be marginally more efficient than using a temporary variable and, by making the code terser, makes it either easier to read or more cryptic, depending on your point of view<ref name="refthree"> refactoring for everyone http://www.ibm.com/developerworks/library/os-ecref/ </ref> | |||
===Encapsulating Fields=== | |||
Generally its not a good practice to expose the class attributes through public interface. Thus, Encapsulating such fields will make such fields as private or protected as appropriate and generate getters and setters for the associated field. | |||
===Changing Method Signature=== | |||
Here we change the change the parameters, visibility, and return type of a method. | |||
== Other Refactorings == | |||
There are a multitude of refactorings. Those that are included with RubyMine<ref name="reffour">RubyMine :: Ruby and Ruby on Rails IDE with smart code completion, syntax highlighting and refactoring http://www.jetbrains.com/ruby/features/ruby_ide.html#Refactorings</ref> include: | |||
<ul> | |||
<li>Rename refactoring | |||
<li>Extract Method | |||
<li>Extract Module | |||
<li>Extract Superclass | |||
<li>Introduce Variable | |||
<li>Introduce Constant | |||
<li>Introduce Field | |||
<li>Introduce Parameter | |||
<li>Inline Variable | |||
<li>Pull Up Members | |||
<li>Push Down Members | |||
<li>Override Method | |||
</ul> | |||
Martin Fowler has online resources for additional refactoring definitions which can be found here http://martinfowler.com/bliki/refactoring.html<ref name="reffive">MF Blicki: refactoring http://martinfowler.com/bliki/refactoring.html</ref> and here http://refactoring.com/catalog/<ref name="refsix">Alpha list of refactorings http://refactoring.com/catalog/</ref>. | |||
==Refactoring support in popular IDE(s)== | |||
{| class="wikitable sortable" style="font-size: 90%; text-align: center; width: auto;" | |||
|- | |||
! IDE | |||
! Language(s) | |||
! Refactoring Support | |||
! Automated Refactoring? | |||
! Number of Refactoring support | |||
! Support for Pattern | |||
! Example | |||
|- | |||
! Borland Delphi | |||
! Object Oriented Pascal | |||
! Rename refactoring, Refactor driven “Find References”, Introduce Variable refactoring, Introduce Field refactoring, Inline Variable refactoring, Change Parameters refactoring, Safe Delete refactoring, Push Members Up / Down refactoring, Pull Members Up refactoring, Extract Superclass refactoring, Extract Interface refactoring, Move Members refactoring, Declare variable refactoring, Declare field refactoring, Extract method refactoring, Find unit/import namespace refactoring, Refactor driven “Find in Files”, Extract to resource string refactoring<ref name="borlandrefactorings>Leveraging What You Have: 10 Top Things Added to Delphi Since Delphi 7 http://edn.embarcadero.com/article/37416</ref> | |||
! Yes | |||
! 17 | |||
! Declare Variable<ref name="borlanddecvar">Increased Productivity with Refactoring, Unit Testing, Help Insight, Error Insight, and Sync Edit in Borland Delphi 2005 http://edn.embarcadero.com/article/33278</ref> | |||
! | |||
---- Before Refactoring | |||
<pre> | |||
procedure TWinForm1.btnOpen_Click(sender: System.Object; | |||
e: System.EventArgs); | |||
begin | |||
if (OpenFileDialog1.ShowDialog = | |||
System.Windows.Forms.DialogResult.OK) then | |||
begin | |||
Assign(f,OpenFileDialog1.FileName); | |||
Reset(f); | |||
try | |||
finally | |||
CloseFile(f); | |||
end; | |||
end; | |||
end; | |||
</pre> | |||
---- After Refactoring | |||
<pre> | |||
procedure TWinForm1.btnOpen_Click(sender: System.Object; | |||
e: System.EventArgs); | |||
var | |||
f: TextFile; | |||
begin | |||
if (OpenFileDialog1.ShowDialog = | |||
System.Windows.Forms.DialogResult.OK) then | |||
begin | |||
Assign(f,OpenFileDialog1.FileName); | |||
Reset(f); | |||
try | |||
finally | |||
CloseFile(f); | |||
end; | |||
end; | |||
end; | |||
</pre> | |||
|- | |||
! Eclipse <ref name='refeclipse'>Eclipse Refactoring Actions http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Freference%2Fref-menu-refactor.htm </ref> | |||
! C, C++, Java | |||
! Rename selected Elements, Move selected elements, Change Method Signature, Extraction, Convert Anonymous Class to Nested, Convert Local Variable to Field, Extract Super class and Interface, push down, pull up, Introduce Indirection, Encapsulate Field, Migrate JAR File, Create & Apply Refatoring Scripts | |||
! Yes | |||
! 27 | |||
! Introduce Factory | |||
! | |||
---- Before Refactoring | |||
int x= p * 5; | |||
p.x; | |||
---- After Refactoring | |||
int x= getFoo(p); (Method Extraction) | |||
p.getX() (Encapsulate Field) | |||
|- | |||
! Kdevelop | |||
! C, C++ | |||
! Several<ref name="kdeveloprefactorings">Kdevelop4: Now with refactoring! http://zwabel.wordpress.com/2008/11/05/kdevelop4-now-with-refactoring/</ref>. Project wide search/replace and local search/replace. | |||
! Yes but very limited. | |||
! 2 | |||
! Rename Class | |||
! Right click on class name and select Rename | |||
|- | |||
! NetBeans <ref name="refnetbeans">Refactoring in NetBeans 4.1 http://java.sun.com/developer/technicalArticles/tools/refactoring/</ref> | |||
! Java | |||
! Renaming fields, methods, classes, or packages, Encapsulating fields, Changing method parameters, Moving classes, | |||
! Yes but very limited | |||
! 4 | |||
! No | |||
! | |||
---- Before Refactoring | |||
<pre> | |||
public class Foo{ | |||
public int n; | |||
public int Compute(int val); | |||
} | |||
</pre> | |||
---- After Refactoring (Encapsulating field) | |||
<pre> | |||
pubic class Foo{ | |||
private int n; | |||
public int getN(); | |||
public void setN(int val); | |||
public int Compute(int arg); | |||
} | |||
</pre> | |||
|- | |||
! Padre | |||
! Perl | |||
! Lexically Rename Variable, Introduce Temporary Variable<ref name="padrerefactorings" >How to do it in Padre http://padre.perlide.org/howto.html</ref> | |||
! Yes | |||
! Unknown | |||
! | |||
! Right click on item to refactor and select refactoring choice from the context menu | |||
|- | |||
! RubyMine | |||
! Ruby | |||
! Safe Delete, Rename Refactorings, Push Members Down, Pull Members Up, Move Refactorings, Introduce Variable, Introduce Parameter, Introduce Field, Introduce Constant, Inline, Extract Superclass, Extract Module, Extract Partial, Extract Method, Copy / Clone. | |||
! Yes | |||
! 15 | |||
! Introduce Temporary | |||
! | |||
---- Before Refactoring | |||
<pre> | |||
c = a * b + 5 | |||
d = 2 * a * b | |||
</pre> | |||
---- After Refactoring | |||
<pre> | |||
t = a * b | |||
c = t + 5 | |||
d = 2 * t | |||
</pre> | |||
|- | |||
! Visual Studio <ref name="refvstudio">7 Refactoring Methods in Visual Studio 2010 http://p2p.wrox.com/content/articles/7-refactoring-methods-visual-studio-2010 </ref> | |||
! C, C++, Java, C# | |||
! Extract Method, Encapsulate Field, Extract Interface, Rename, Promote Variable to Parameter(Changing method signature), Generate Method Stub(Used for testing purposes) | |||
! Yes | |||
! 7 | |||
! No | |||
! Promoting Variable to Parameter | |||
---- Before Refactoring | |||
public void MethodA() | |||
{ | |||
MethodB(); | |||
} | |||
public void MethodB() | |||
{ | |||
string output = "Test String"; | |||
MessageBox.Show( output); | |||
} | |||
---- After Refactoring | |||
public void MethodA() | |||
{ | |||
MethodB("Test String"); | |||
} | |||
public void MethodB(string output) | |||
{ | |||
MessageBox.Show( output); | |||
} | |||
|} | |||
== Refactoring to Patterns== | |||
Refactoring to Patterns is the process of improving the design of existing code -- with patterns, the classic solutions to recurring design problems. This is still a young area of research and currently IDEs hardly provide any support for Automated Design Pattern Refactoring. | |||
A lot of work is currently in progress in this fairly young research topic. Using automated refactorings to move towards, to, or away from a pattern is completely different from using a tool to generate pattern code. Pattern code generators provide an excellent way to over-engineer your code but They provide code does not include testing. By contrast, refactoring lets you discover small design improvements you can safely make to go towards, to, or away from a pattern implementation. <ref name="refactor">Introduction to Refactoring to patterns http://www.informit.com/articles/article.aspx?p=360842&seqNum=11</ref>. The refactoring support in an IDE attracted the application developers who used to code in editors to move to IDE. | |||
As refactoring tools continue to implement low-level refactorings, like Extract Method, Extract Class , and Pull Up Method , it becomes easier to transform designs by executing sequences of automated refactorings. This has important implications for pattern-directed refactorings because the mechanics for these refactorings are composed of low-level refactorings. In the future, we can hope to see more and more low level refactoring support such that tools could suggest the refactorings that could help in improving the design of the code. | |||
==References== | ==References== | ||
<references/> | <references/> |
Latest revision as of 03:32, 3 November 2011
Automatic Refactoring
Introduction
Refactoring is a technique for restructuring an existing code, altering its internal structure without changing its external behavior. Its done as a series of small transformations. Each transformation does little, but a sequence of transformations can produce a significant restructuring. Since each refactoring is small, it's less likely to go wrong. The system is also kept fully working after each small refactoring, reducing the chances that a system can get seriously broken during the restructuring.<ref name="refone"> Refactoring Home Page http://refactoring.com/ </ref> As people make changes to the code to realize their short term goals without fully understanding the design of code, the code loses its structure. The refactoring work is done to remove bits that aren’t really in the right place. Loss of the structure of code has a cumulative effect. The harder it is to see the design in the code, the harder it is to preserve it, and the more rapidly it decays. Regular refactoring helps code retain its shape. <ref name="reftwo"> Why should you Refactor http://sourcemaking.com/refactoring/why-should-you-refactor </ref>
Fully autonomous factoring doesn't appear to exist at this time in the IDE(s) described below. However there are papers Inducing Evolution-Robust Pointcuts <Ref name="refseven">Inducing Evolution-Robust Pointcuts, Braem, M.</ref> and Automatic Refactoring of Erlang Programs<ref name="refeight">Automatic Refactoring of Erlang Programs http://www.ece.cmu.edu/~aavgerin/papers/PPDP09.pdf</ref> that point the way to the future of refactoring that can be fully automated. In the context of this wiki article, automatic refactoring means automated refactoring under programmer control and guidance.
Common Refactoring Techniques
Extraction Refactoring
There are several refactoring techniques related to extraction: Extract method, Extract local variables, extract constants. The first method "Extract method will create a new method from code you've selected. Extract Local Variable refactoring takes an expression that is being used repeatedly and assigns it to a local variable. Extract constant refactoring is to select a static, constant expression, which the refactoring will convert to a static final constant. This is useful for removing hard-coded numbers and strings from your code
Inline Refactoring
This type refactoring is the reverse of local variable extraction, in which we remove a local variable and use the value of the variable(typically an expression) in the place where the variable is used. This can be marginally more efficient than using a temporary variable and, by making the code terser, makes it either easier to read or more cryptic, depending on your point of view<ref name="refthree"> refactoring for everyone http://www.ibm.com/developerworks/library/os-ecref/ </ref>
Encapsulating Fields
Generally its not a good practice to expose the class attributes through public interface. Thus, Encapsulating such fields will make such fields as private or protected as appropriate and generate getters and setters for the associated field.
Changing Method Signature
Here we change the change the parameters, visibility, and return type of a method.
Other Refactorings
There are a multitude of refactorings. Those that are included with RubyMine<ref name="reffour">RubyMine :: Ruby and Ruby on Rails IDE with smart code completion, syntax highlighting and refactoring http://www.jetbrains.com/ruby/features/ruby_ide.html#Refactorings</ref> include:
- Rename refactoring
- Extract Method
- Extract Module
- Extract Superclass
- Introduce Variable
- Introduce Constant
- Introduce Field
- Introduce Parameter
- Inline Variable
- Pull Up Members
- Push Down Members
- Override Method
Martin Fowler has online resources for additional refactoring definitions which can be found here http://martinfowler.com/bliki/refactoring.html<ref name="reffive">MF Blicki: refactoring http://martinfowler.com/bliki/refactoring.html</ref> and here http://refactoring.com/catalog/<ref name="refsix">Alpha list of refactorings http://refactoring.com/catalog/</ref>.
Refactoring support in popular IDE(s)
IDE | Language(s) | Refactoring Support | Automated Refactoring? | Number of Refactoring support | Support for Pattern | Example |
---|---|---|---|---|---|---|
Borland Delphi | Object Oriented Pascal | Rename refactoring, Refactor driven “Find References”, Introduce Variable refactoring, Introduce Field refactoring, Inline Variable refactoring, Change Parameters refactoring, Safe Delete refactoring, Push Members Up / Down refactoring, Pull Members Up refactoring, Extract Superclass refactoring, Extract Interface refactoring, Move Members refactoring, Declare variable refactoring, Declare field refactoring, Extract method refactoring, Find unit/import namespace refactoring, Refactor driven “Find in Files”, Extract to resource string refactoring<ref name="borlandrefactorings>Leveraging What You Have: 10 Top Things Added to Delphi Since Delphi 7 http://edn.embarcadero.com/article/37416</ref> | Yes | 17 | Declare Variable<ref name="borlanddecvar">Increased Productivity with Refactoring, Unit Testing, Help Insight, Error Insight, and Sync Edit in Borland Delphi 2005 http://edn.embarcadero.com/article/33278</ref> |
Before Refactoring procedure TWinForm1.btnOpen_Click(sender: System.Object; e: System.EventArgs); begin if (OpenFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK) then begin Assign(f,OpenFileDialog1.FileName); Reset(f); try finally CloseFile(f); end; end; end; After Refactoring procedure TWinForm1.btnOpen_Click(sender: System.Object; e: System.EventArgs); var f: TextFile; begin if (OpenFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK) then begin Assign(f,OpenFileDialog1.FileName); Reset(f); try finally CloseFile(f); end; end; end; |
Eclipse <ref name='refeclipse'>Eclipse Refactoring Actions http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Freference%2Fref-menu-refactor.htm </ref> | C, C++, Java | Rename selected Elements, Move selected elements, Change Method Signature, Extraction, Convert Anonymous Class to Nested, Convert Local Variable to Field, Extract Super class and Interface, push down, pull up, Introduce Indirection, Encapsulate Field, Migrate JAR File, Create & Apply Refatoring Scripts | Yes | 27 | Introduce Factory |
Before Refactoring int x= p * 5; p.x; After Refactoring int x= getFoo(p); (Method Extraction) p.getX() (Encapsulate Field) |
Kdevelop | C, C++ | Several<ref name="kdeveloprefactorings">Kdevelop4: Now with refactoring! http://zwabel.wordpress.com/2008/11/05/kdevelop4-now-with-refactoring/</ref>. Project wide search/replace and local search/replace. | Yes but very limited. | 2 | Rename Class | Right click on class name and select Rename |
NetBeans <ref name="refnetbeans">Refactoring in NetBeans 4.1 http://java.sun.com/developer/technicalArticles/tools/refactoring/</ref> | Java | Renaming fields, methods, classes, or packages, Encapsulating fields, Changing method parameters, Moving classes, | Yes but very limited | 4 | No |
Before Refactoring public class Foo{ public int n; public int Compute(int val); } After Refactoring (Encapsulating field) pubic class Foo{ private int n; public int getN(); public void setN(int val); public int Compute(int arg); } |
Padre | Perl | Lexically Rename Variable, Introduce Temporary Variable<ref name="padrerefactorings" >How to do it in Padre http://padre.perlide.org/howto.html</ref> | Yes | Unknown | Right click on item to refactor and select refactoring choice from the context menu | |
RubyMine | Ruby | Safe Delete, Rename Refactorings, Push Members Down, Pull Members Up, Move Refactorings, Introduce Variable, Introduce Parameter, Introduce Field, Introduce Constant, Inline, Extract Superclass, Extract Module, Extract Partial, Extract Method, Copy / Clone. | Yes | 15 | Introduce Temporary |
Before Refactoring c = a * b + 5 d = 2 * a * b After Refactoring t = a * b c = t + 5 d = 2 * t |
Visual Studio <ref name="refvstudio">7 Refactoring Methods in Visual Studio 2010 http://p2p.wrox.com/content/articles/7-refactoring-methods-visual-studio-2010 </ref> | C, C++, Java, C# | Extract Method, Encapsulate Field, Extract Interface, Rename, Promote Variable to Parameter(Changing method signature), Generate Method Stub(Used for testing purposes) | Yes | 7 | No | Promoting Variable to Parameter
Before Refactoring public void MethodA() { MethodB(); } public void MethodB() { string output = "Test String"; MessageBox.Show( output); } After Refactoring public void MethodA() { MethodB("Test String"); } public void MethodB(string output) { MessageBox.Show( output); } |
Refactoring to Patterns
Refactoring to Patterns is the process of improving the design of existing code -- with patterns, the classic solutions to recurring design problems. This is still a young area of research and currently IDEs hardly provide any support for Automated Design Pattern Refactoring. A lot of work is currently in progress in this fairly young research topic. Using automated refactorings to move towards, to, or away from a pattern is completely different from using a tool to generate pattern code. Pattern code generators provide an excellent way to over-engineer your code but They provide code does not include testing. By contrast, refactoring lets you discover small design improvements you can safely make to go towards, to, or away from a pattern implementation. <ref name="refactor">Introduction to Refactoring to patterns http://www.informit.com/articles/article.aspx?p=360842&seqNum=11</ref>. The refactoring support in an IDE attracted the application developers who used to code in editors to move to IDE.
As refactoring tools continue to implement low-level refactorings, like Extract Method, Extract Class , and Pull Up Method , it becomes easier to transform designs by executing sequences of automated refactorings. This has important implications for pattern-directed refactorings because the mechanics for these refactorings are composed of low-level refactorings. In the future, we can hope to see more and more low level refactoring support such that tools could suggest the refactorings that could help in improving the design of the code.
References
<references/>