重构:用方法对象替换方法解释
Refactoring: Replace Method with Method Object explanation
我正在寻找重构一个太长的方法。搜索我发现了这个技巧:Replace Method with Method Object 但我一点也不明白。
如果重构的方法是:
public class Order {
//Method to refactor
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
//compute impl
}
//.....
}
对于 Web 示例,重构 用方法对象替换方法 将如下所示:
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();
但是 PriceCalculator 如何获取 primaryBasePrice、secondaryBasePrice、tertiaryBasePrice 值来进行计算?
和重构前一样。
如果你看原始代码,primaryBasePrice
、secondaryBasePrice
和tertiaryBasePrice
是本地变量,其值在某处设置在 //compute impl
部分。
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
// compute impl
// all base price variables are assigned somewhere in here
}
重构后,compute()
方法具有 //compute impl
代码的副本,并简单地将完全相同的值分配给 PriceCalculator
中的字段,就像它对局部变量所做的那样重构之前。
我们需要传递对 Order
对象的引用,以防这些值取决于其方法或内部状态。
例如,如果我们之前有
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
// some of compute impl
primaryBasePrice = getPrimary();
secondaryBasePrice = getSecondary();
tertiaryBasePrice = getTertiary();
// the rest of compute impl
}
重构后,我们会变成类似
的东西
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
}
所以回答你的两个问题:
But how PriceCalculator gets primaryBasePrice, secondaryBasePrice,
tertiaryBasePrice values to do the compute?
。是的,你是对的,你需要将它们作为构造函数参数发送。
Otherwise, why pass in the constructor order instance reference? Why
is needed?
您需要传递订单实例引用才能调用订单的其他方法。在你给出的例子中,它是一个简单的方法,但在其他一些方法中你可能会调用订单的一些方法......
这种重构技术的一个问题是,如果您的原始方法访问 Order 的私有方法,那么您必须使它们受到包保护或在目标方法对象中复制这些方法...
如果你将这些私有方法作为包保护,那么你会得到紧耦合、功能嫉妒和其他问题
我正在寻找重构一个太长的方法。搜索我发现了这个技巧:Replace Method with Method Object 但我一点也不明白。
如果重构的方法是:
public class Order {
//Method to refactor
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
//compute impl
}
//.....
}
对于 Web 示例,重构 用方法对象替换方法 将如下所示:
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();
但是 PriceCalculator 如何获取 primaryBasePrice、secondaryBasePrice、tertiaryBasePrice 值来进行计算?
和重构前一样。
如果你看原始代码,primaryBasePrice
、secondaryBasePrice
和tertiaryBasePrice
是本地变量,其值在某处设置在 //compute impl
部分。
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
// compute impl
// all base price variables are assigned somewhere in here
}
重构后,compute()
方法具有 //compute impl
代码的副本,并简单地将完全相同的值分配给 PriceCalculator
中的字段,就像它对局部变量所做的那样重构之前。
我们需要传递对 Order
对象的引用,以防这些值取决于其方法或内部状态。
例如,如果我们之前有
public double price() {
double primaryBasePrice;
double secondaryBasePrice;
double tertiaryBasePrice;
// some of compute impl
primaryBasePrice = getPrimary();
secondaryBasePrice = getSecondary();
tertiaryBasePrice = getTertiary();
// the rest of compute impl
}
重构后,我们会变成类似
的东西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
}
所以回答你的两个问题:
But how PriceCalculator gets primaryBasePrice, secondaryBasePrice, tertiaryBasePrice values to do the compute?
。是的,你是对的,你需要将它们作为构造函数参数发送。
Otherwise, why pass in the constructor order instance reference? Why is needed?
您需要传递订单实例引用才能调用订单的其他方法。在你给出的例子中,它是一个简单的方法,但在其他一些方法中你可能会调用订单的一些方法......
这种重构技术的一个问题是,如果您的原始方法访问 Order 的私有方法,那么您必须使它们受到包保护或在目标方法对象中复制这些方法...
如果你将这些私有方法作为包保护,那么你会得到紧耦合、功能嫉妒和其他问题