The Artima Developer Community
Sponsored Link

Weblogs Forum
Refactoring 2.0

24 replies on 2 pages. Most recent reply: Mar 28, 2007 11:24 PM by Michael Feathers

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 24 replies on 2 pages [ 1 2 | » ]
Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Refactoring 2.0 (View in Weblogs)
Posted: Mar 13, 2007 6:28 PM
Reply to this message Reply
Summary
What automated refactorings would you like to see?
Advertisement

Automated refactoring has come a long way. I remember, years ago, when I first saw John Brant and Don Robert’s Smalltalk Refactoring Browser at OOPSLA. I had a sinking feeling in my chest. It was great, it was powerful, and I couldn’t imagine Java tool vendors ever creating anything similar. After all, there wasn’t any demand – people didn’t even know what refactoring was. I thought that automated refactoring was going to be just another niche idea that started and ended in academia.

Well, I was wrong and I’m glad that I was wrong. Vendors took the leap. JetBrains (under the name Intellij) started to create a refactoring plug-in and then they decided to create Idea, a full IDE. Eclipse came along as well, adding refactoring support from the beginning. Now, automated refactoring tools are commonplace in the Java world but I think we can go further.

Here’s a little hit list of things I’d like to see in a refactoring tool; things I do all the time. I’m not sure that all of them can be automated easily, but I’d love to see an attempt.

Extract Class

Yes, Eclipse and Idea give us Extract Superclass, but why don’t they give us Extract Class? It seems like it would be relatively simple. An IDE could use roughly the same dialog that it uses for Extract Superclass, but instead of creating a superclass the IDE could create a new class, declare an instance of it in the old class, and then move all of the fields and methods that you’ve selected.

Introduce Instance Delegator

This is a minor one, but it’s handy. There are times when I want to create a delegating method for a static method. Unfortunately, Eclipse always makes the delegator static. It would be nice if there was a checkbox for this. I often make instance delegators when I’m trying to create a seam around a static method call.

Introduce Parameter Object

I’d like to be able to select a set of parameters to a method and have my IDE create a new class for them, fixing up the code as it does it so that all of the references to the parameters are now references to the class. Again, this is handy when moving away from overly long parameter lists. I don’t think this has to be limited to parameters either. You should be able to select any group of fields or local variables and ask the IDE to create a class for them.

Encapsulate Class/Package

Many API developers still don’t realize that when they make classes and methods final they often make it impossible to mock them without special support. Eclipse makes it easy to create delegate classes, but it’s still a little harder than it needs to be. It would be nice to have a feature which takes a set of classes or a package and generates an interface and wrapper for each class. I can’t imagine using it all the time, but it sure would come in handy when I'm working with some of the more paranoid frameworks and libraries.

Move Statement

This is the big one. I’d like to be able to select a statement and move it up above the statement above it or below the statement below it, but only if the IDE can be certain that behavior will be preserved. In general, this problem is intractable – you can’t always tell whether a move would preserve behavior, but there are computable cases. No one would want to have their IDE freeze for as long as it takes to compute the worst of them, but if a tool allowed moves in the simple cases, I’d be happy.

That’s my short list for today. What would you like to see?


Alberto Savoia

Posts: 95
Nickname: agitator
Registered: Aug, 2004

Re: Refactoring 2.0 Posted: Mar 13, 2007 7:53 PM
Reply to this message Reply
Hi Michael,

Great topic. Refactoring is addictive and it's hard to imagine how we ever lived without it.

Some quick thoughts on your proposed ideas (and I will try to think of my own wish-list a little later).

> <h3>Extract Class</h3>
>
> <p>Yes, Eclipse and Idea give us <i>Extract
> Superclass</i>, but why don’t they give us <i>Extract
> Class</i>? It seems like it would be relatively simple.
> An IDE could use roughly the same dialog that it uses for
> r <i>Extract Superclass</i>, but instead of creating a
> superclass the IDE could create a new class, declare an
> instance of it in the old class, and then move all of the
> fields and methods that you’ve selected.</p>

Gets my vote. I always wished for this one and I am surprised it's not already supported. I bet you that people working with legacy code would use this more often than Extract Superclass.

> <h3>Introduce Parameter Object</h3>
>
> <p>I’d like to be able to select a set of parameters to a
> method and have my IDE create a new class for them, fixing
> up the code as it does it so that all of the references to
> the parameters are now references to the class. Again,
> this is handy when moving away from overly long parameter
> lists. I don’t think this has to be limited to parameters
> either. You should be able to select any group of fields
> or local variables and ask the IDE to create a class for
> them.</p>

Another good one I've often wished for. As with the previous one, it would be extremely useful for cleaning up legacy code.

> <h3>Move Statement</h3>
>
> <p>This is the big one. I’d like to be able to select a
> statement and move it up above the statement above it or
> below the statement below it, but only if the IDE can be
> certain that behavior will be preserved. In general, this
> problem is intractable – you can’t always tell whether a
> move would preserve behavior, but there are computable
> cases. No one would want to have their IDE freeze for as
> long as it takes to compute the worst of them, but if a
> tool allowed moves in the simple cases, I’d be happy.</p>

Interesting. Here's one case where having some tests can serve as some kind proxy for checking that it's a "safe" refactoring - at least as far as the existing tests are concerned. A failing test would definitely show that the refactoring is not safe. Passing tests give you some confidence, but no certainty. Perhaps with this type of refactoring the IDE could automatically run existing tests, check test coverage, and tell you where you stand.

Chris Morris

Posts: 8
Nickname: chrismo
Registered: Jan, 2004

Re: Refactoring 2.0 Posted: Mar 14, 2007 12:38 AM
Reply to this message Reply
Couple things:

(a) Eclipse request for Introduce Parameter Object refactoring: https://bugs.eclipse.org/bugs/show_bug.cgi?id=102287

(b) entry in my blog on how to do it with the current tools in Eclipse: http://www.clabs.org/blogki/blogki.cgi?page=/ComputersAndTechnology/IntroduceParameterObjectPseudoRefactoringInEclipse

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Refactoring 2.0 Posted: Mar 14, 2007 8:52 AM
Reply to this message Reply
> > <h3>Extract Class</h3>
> >
> > <p>Yes, Eclipse and Idea give us <i>Extract
> > Superclass</i>, but why don’t they give us <i>Extract
> > Class</i>? It seems like it would be relatively
> simple.
> > An IDE could use roughly the same dialog that it uses
> for
> > r <i>Extract Superclass</i>, but instead of creating a
> > superclass the IDE could create a new class, declare an
> > instance of it in the old class, and then move all of
> the
> > fields and methods that you’ve selected.</p>
>
> Gets my vote. I always wished for this one and I am
> surprised it's not already supported. I bet you that
> people working with legacy code would use this more often
> than Extract Superclass.

I keep wondering why Extract Class isn't there already. The only thing I can imagine is that it isn't as apt to succeed cleanly as Extract Superclass. If you select a field to move, and don't select its encapsulating methods, the tool would have to make it visible or introduce accessors.

Then, there's the constructor case. The safest thing would probably be to create the new object at the bottom of each constructor and, at that point, pass everything the object needs as an argument. Seems a little messy, but doable.

I know there's a tendency in refactoring tools to give people the bits that they can use to do the composite refactorings rather than the composite refactoring, and Move Field and Move Method are there, but Extract Class would be very useful.

> > <h3>Move Statement</h3>
>
> Interesting. Here's one case where having some tests can
> serve as some kind proxy for checking that it's a "safe"
> refactoring - at least as far as the existing tests are
> concerned. A failing test would definitely show that the
> refactoring is not safe. Passing tests give you some
> confidence, but no certainty. Perhaps with this type of
> refactoring the IDE could automatically run existing
> tests, check test coverage, and tell you where you stand.

Yes. I still think there's something that could be done analytically though. I saw one attempt at this with a refactoring tool that was under development by a company in the UK. I don't know how deep their analysis went, however.

I guess a tool could generate tests for that sort of thing, though, by manipulating byte code... do just enough analysis to know where it would have to detect change for that particular move.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Refactoring 2.0 Posted: Mar 14, 2007 8:55 AM
Reply to this message Reply
> Couple things:
>
> (a) Eclipse request for Introduce Parameter Object
> refactoring:
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=102287
>
> (b) entry in my blog on how to do it with the current
> tools in Eclipse:
> http://www.clabs.org/blogki/blogki.cgi?page=/ComputersAndTe
> chnology/IntroduceParameterObjectPseudoRefactoringInEclipse

Chris, cool. I really think it would be great if Eclipse had it. I can imagine fear too. If I was a tool vendor, I'd probably be leery about making it easy to introduce a data object but for people who refactor like we do, Introduce Parameter Object would be great.

Martin Ankerl

Posts: 9
Nickname: sunitram
Registered: Mar, 2005

Re: Refactoring 2.0 Posted: Mar 14, 2007 5:30 PM
Reply to this message Reply
I'd like to see

Make Variables final: Add a "final" to each and every variable declaration, to prevent overwriting variables.

Convert sysout() to LOG.info()

Use Minimal Interface: When you write ArrayList x = new ArrayList(), replace this with the minimal interface that still produces compileable code, e.g. List x = new ArrayList();.

Roly Perera

Posts: 1
Nickname: rolyp
Registered: Mar, 2007

Re: Refactoring 2.0 Posted: Mar 15, 2007 3:43 AM
Reply to this message Reply
Hi Michael,

As you know our domain/j project stalled some time ago, but I recently made our old Flash demos available on my blog (http://www.dynamicaspects.org/blog). They show some of the refactorings you mentioned, including Move Statement (although a variant which pushes the statement into the following method call) and Introduce Parameter Object, plus some others. Nothing you haven't seen before of course.

I'm still extremely interested the potential of a tool which supports "micro-refactoring", there just happens to be a slightly bigger problem currently pushed on my stack, namely how to build highly stateful, interactive systems that are reliable.

cheers,
Roly

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Refactoring 2.0 Posted: Mar 15, 2007 4:02 AM
Reply to this message Reply
I am not sure if everyone is aware that the next version of Netbeans has a system that allows you to write your own refactorings, for simple stuff there is an easy to use domain specific language, e.g.:

($T)$a => $a :: $a instanceof $T;

Means transform ($T)$a into $a provided that $a is an instance of $T and therefore this refactoring removes unecessary casts. For more complicated stuff there is an API based on the Tree API (the Tree API is used internally by the compiler and exposed for annotations processing).

jamie mccrindle

Posts: 3
Nickname: dkfn
Registered: Apr, 2003

Re: Refactoring 2.0 Posted: Mar 15, 2007 8:54 AM
Reply to this message Reply
I want the mother of all refactoring's:

Private method to Strategy Pattern

Start with a private method on a class
Create an interface with that private method on it as a public method
Create a new class that implements the interface with the original code for the private method as a public implementation
Create a default singleton on the interface that is an instance of the new class
Create a reference to the interface as a member variable on the original class
Optionally create a setter or new constructor that takes in an alternate implementation of the Strategy interface on the original class.
Replace all references to private method with a reference to the Strategy member variable method call.

If the private method uses member variables in the class, these could be introduced as parameters.

Ivan Lazarte

Posts: 91
Nickname: ilazarte
Registered: Mar, 2006

Re: Refactoring 2.0 Posted: Mar 15, 2007 1:58 PM
Reply to this message Reply
if you create an instance, I believe you can right click on the instance and create non-static delegate methods in eclipse.

Dave Benjamin

Posts: 10
Nickname: ramenboy
Registered: Nov, 2003

Re: Refactoring 2.0 Posted: Mar 16, 2007 11:29 AM
Reply to this message Reply
Maybe this is a totally impractical idea, but I think it would be amazing if you could select a block of code and perform a "Reimplement Algorithm" refactoring (for lack of a better name) that would change the selected code in ways that preserve its behavior. Perhaps a keyboard shortcut could allow you to rotate forward and backward through various reimplementations. You could pick the one that is cleanest, visually, or the one that has the best performance, or the least amount of code.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Refactoring 2.0 Posted: Mar 16, 2007 11:34 AM
Reply to this message Reply
> As you know our domain/j project stalled some time ago,
> but I recently made our old Flash demos available on my
> blog (http://www.dynamicaspects.org/blog). They show some
> of the refactorings you mentioned, including Move
> Statement (although a variant which pushes the statement
> into the following method call) and Introduce Parameter
> Object, plus some others. Nothing you haven't seen before
> of course.
>
> I'm still extremely interested the potential of a tool
> which supports "micro-refactoring", there just happens to
> be a slightly bigger problem currently pushed on my stack,
> namely how to build highly stateful, interactive systems
> that are reliable.

Roly, yes it's a shame that work didn't go further. I hope someone picks it up.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Refactoring 2.0 Posted: Mar 16, 2007 11:49 AM
Reply to this message Reply
> I'd like to see
>
> Make Variables final: Add a "final" to each and every
> variable declaration, to prevent overwriting variables.
>
> Convert sysout() to LOG.info()
>
> Use Minimal Interface: When you write ArrayList x =
> new ArrayList()
, replace this with the minimal
> interface that still produces compileable code, e.g.
> List x = new ArrayList();.

Yes, in retrospect it would've been nice to have final as default. I think that whenever we discover something that we want to add to every one of a particular language element to make it align with our wishes, it's telling us that we need to change our language or change our language. :-)

It would be a neat feature, though. I've been thinking about about what environments can do for us. Imagine something like this: you flip a switch in Eclipse and it changes all references that can be final to final. If you really want to modify a variable you can delete final on a particular declaration. But, here's the trick. When you look at your code on disk, the final declarations are not there. They are just a restriction in the IDE to force you to think about mutability. I hope that we see this sort of feature in the future.

Re minimal interfaces, Eclipse has a refactoring for that: 'generalize declared type.'

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Refactoring 2.0 Posted: Mar 16, 2007 11:50 AM
Reply to this message Reply
> Maybe this is a totally impractical idea, but I think it
> would be amazing if you could select a block of code and
> perform a "Reimplement Algorithm" refactoring (for lack of
> a better name) that would change the selected code in ways
> that preserve its behavior. Perhaps a keyboard shortcut
> could allow you to rotate forward and backward through
> various reimplementations. You could pick the one that is
> cleanest, visually, or the one that has the best
> performance, or the least amount of code.

That's a neat idea. The hard part is knowing how how deep to go in analysis when looking for side effects. I wonder if anyone has done any research into this.. algorithm rewriting.

Jeff Langr

Posts: 6
Nickname: jlangr
Registered: Oct, 2003

Re: Refactoring 2.0 Posted: Mar 16, 2007 2:17 PM
Reply to this message Reply
extract local variable to setup method

Flat View: This topic has 24 replies on 2 pages [ 1  2 | » ]
Topic: Refactoring 2.0 Previous Topic   Next Topic Topic: Deterministic Software Development


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us