I was looking for refactoring a too length method. Searching I found this technique: Replace Method with Method Object but I don't understand at all.
If the method to refactor is:
public class Order {
//Method to refactor
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
//compute impl
}
//.....
}
public class Order {
//Method refactored
public double price() {
return new PriceCalculator(this).compute();
}
//.......
}
//Method object
public class PriceCalculator {
private double primaryBasePrice;
private double secondaryBasePrice;
private double tertiaryBasePrice;
public PriceCalculator(Order order) {
//??
}
public double compute() {
// impl
}
}
PriceCalculator
primaryBasePrice
secondaryBasePrice
tertiaryBasePrice
//Method object
public class PriceCalculator {
private double primaryBasePrice;
private double secondaryBasePrice;
private double tertiaryBasePrice;
public PriceCalculator(Order order, double primaryBasePrice,
double secondaryBasePrice, double tertiaryBasePrice) {
this.primaryBasePrice = primaryBasePrice;
this.secondaryBasePrice = secondaryBasePrice;
this.tertiaryBasePrice = tertiaryBasePrice;
}
public double compute() {
// impl
}
}
order
order
return new PriceCalculator(this, primaryBasePrice, secondaryBasePrice, tertiaryBasePrice).compute();
order
return new PriceCalculator(primaryBasePrice, secondaryBasePrice, tertiaryBasePrice).compute();
But how PriceCalculator gets primaryBasePrice, secondaryBasePrice, tertiaryBasePrice values to do the compute?
The same way it was before refactoring.
If you look at the original code, primaryBasePrice
, secondaryBasePrice
and tertiaryBasePrice
are local variables, whose values are being set somewhere in the //compute impl
section.
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
// compute impl
// all base price variables are assigned somewhere in here
}
After refactoring, the compute()
method has a copy of the //compute impl
code, and simply assigns the exact same values to the fields in PriceCalculator
as it did to the local variables before refactoring.
We need to pass in a reference to the Order
object in case those values are dependent on its methods or internal state.
For instance, if we previously had
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
// some of compute impl
primaryBasePrice = getPrimary();
secondaryBasePrice = getSecondary();
tertiaryBasePrice = getTertiary();
// the rest of compute impl
}
after refactoring, we would instead have something like
public double compute() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
// some of compute impl
primaryBasePrice = order.getPrimary();
secondaryBasePrice = order.getSecondary();
tertiaryBasePrice = order.getTertiary();
// the rest of compute impl
}