Refactoring: Introduce Foreign Method vs Extract Method
For some time I was confused about these two refactorings from Martin Fowler’s Refactoring book. They seemed almost the same to me.
What each of them is
Introduce Foreign Method
When you use a library/extension/framework and it doesn’t include some functionality that you need, you can add said functionality in your code, making this method a foreign one from the library’s point of view. There is also a description on Refactoring Guru. The examples in both the Refactoring book and the article on Refactoring Guru add a nextDay method as a foreign extension to Java’s Date
class.
class Report {
// ...
void sendReport() {
Date nextDay = new Date(previousEnd.getYear(),
previousEnd.getMonth(), previousEnd.getDate() + 1);
// ...
}
}
class Report {
// ...
void sendReport() {
Date newStart = nextDay(previousEnd);
// ...
}
private static Date nextDay(Date arg) {
return new Date(arg.getYear(), arg.getMonth(), arg.getDate() + 1);
}
}
Extract Method
When you have some parts of your code which seem to belong together in a group, you can create a new method to contain them. Here is the description from Refactoring Guru. The examples in both the Refactoring book and the article on Refactoring Guru group two printing statements into one method printDetails
.
void printOwing() {
printBanner();
// Print details.
System.out.println("name: " + name);
System.out.println("amount: " + getOutstanding());
}
void printOwing() {
printBanner();
printDetails(getOutstanding());
}
void printDetails(double outstanding) {
System.out.println("name: " + name);
System.out.println("amount: " + outstanding);
}
The difference between the two
It is difficult to find one. Both refactorings take some inline code and put it into a new method. After some thinking about them, there seems to be a subtle difference, which is more intentional than structural — to have an Introduce Foreign Method, there needs to be an external dependency that you have no access to and cannot change. So if you have the intent to augment the external dependency in some way, this makes the refactoring an Introduce Foreign Method, otherwise you have an Extract Method.
The commonalities between the two
The last sentence from the above section on differences implies that both refactoring are Extract Method, but only one of them is an Introduce Foreign Method. This means that Introduce Foreign Method is a subset of Extract Method. Putting some inline code in a new method is an Extract Method, however when there is an additional intent present, it makes the refactoring a more specific type of Extract Method, i.e. Introduce Foreign Method. Here pic:
I am unable to find any relation between the two refactorings in neither mr. Folwer’s book, nor in the Refactoring Guru website. Which means my view is not necessarily shared by the authors or the community. Still, Introduce Foreign Method being a subset of Extract Method is how I see things and also I use it as a way to remember them more easily. Helps to kinda structure the refactorings catalogue in my head.