Reputation: 899
I'm refactoring some code to use polymorphism rather than conditionals. I want to replace the two methods below with a single, overridden method called "transferData", then have two subclasses - an "Uploader" and a "Downloader" with "transferData" as the method to call.
public class Example {
int direction;
public Example(int direction) {
this.direction = direction;
}
public void upload() {
}
public void download() {
}
}
What automated refactoring can I do to minimise the amount of manual changes I need to perform? So far I have:
What is the best way to wrap these method calls, updating their existing call sites appropriately without breaking all my existing code and tests?
Upvotes: 0
Views: 577
Reputation: 31648
I can't think of a completely pain-free way to do it. The way I show below will still cause some compile errors along the way that you need to fix before moving to the next step. But I actually think that is good feedback because you will see what still needs to be fixed, and will know when everything has been fixed.
The easiest way is to modify the parent class first to use a single transferData()
method and then later use subclasses to split up the logic.
Step 1:
public class Example {
int direction;
public Example(int direction) {
this.direction = direction;
}
public void transferData(){
if(direction>0){
upload();
}else{
download();
}
}
public void upload() {
}
public void download() {
}
}
Step 2: make upload()
and download()
no longer public. Change client calls to use transferData() instead.
I can't think of any built-in eclipse automation tools to fix this. I guess you can do a rename method to change one of them in Step 1 but that will still cause compile errors for the other method to be changed. On the bright side, this will cause compile errors when a client is calling a non-visible method so after a little pain of fixing them all, once everything compiles should should be good to move on to the next step. (Assuming you aren't using reflection to make some calls)
public class Example {
...
private void upload() {
}
private void download() {
}
}
Step 3: replace all constructions of Example with Factory. Again for simplicity, you can make the Example constructor private to cause compilation errors to help track all uses.
Step 4: Modify factory to return subclasses instead.
Once everything compiles, all tests should still pass.
Hope that helps.
Upvotes: 1