重构:使用方法对象说明替换方法

时间:2016-09-06 20:56:39

标签: java c# coding-style refactoring

我一直在寻找重构太长的方法。搜索我发现了这种技术: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如何获得primaryBasePricesecondaryBasePricetertiaryBasePrice值来进行计算?

我只看到可以将构造函数中的值传递给下一个:

//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();

2 个答案:

答案 0 :(得分:3)

但是PriceCalculator如何获得primaryBasePrice,secondaryBasePrice,tertiaryBasePrice值来进行计算?

与重构之前的方式相同。

如果您查看原始代码,primaryBasePricesecondaryBasePricetertiaryBasePrice本地变量,其值将设置在{{1}的某处}。section。

//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
}

答案 1 :(得分:1)

所以回答你的问题:

  1.   

    但是PriceCalculator如何获得primaryBasePrice,secondaryBasePrice,   使用tertiaryBasePrice值进行计算?

  2. 。是的,你是对的,你需要将它们作为构造函数参数发送。

    1.   

      否则,为什么传入构造函数的命令实例引用?为什么   需要吗?

    2. 您需要传递订单实例引用才能调用Order的其他方法。在你给出的例子中,这是一个简单的方法,但在其他一些方法中,你可能会调用一些Order的方法......

      这种重构技术的一个问题是,如果您的原始方法访问Order的私有方法,那么您必须使它们受到包保护或在目标方法对象中复制这些方法...

      如果你将这些私有方法作为包保护,那么你会得到紧密耦合,功能嫉妒和其他问题