【问题标题】:Refactoring: Replace Method with Method Object explanation重构:用方法对象替换方法解释
【发布时间】:2016-09-06 20:56:38
【问题描述】:

我正在寻找重构太长的方法。搜索我发现了这个技术:Replace Method with Method Object 但我完全不明白。

如果要重构的方法是:

public class Order {
  //Method to refactor
  public double price() {
    double primaryBasePrice;
    double secondaryBasePrice;
    double tertiaryBasePrice;

     //compute impl
  }

 //.....
}

对于 web 示例,重构 Replace Method with Method Object 将如下所示:

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

【问题讨论】:

    标签: java c# coding-style refactoring


    【解决方案1】:

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

    与重构之前的方式相同。

    如果您查看原始代码,primaryBasePricesecondaryBasePricetertiaryBasePrice本地 变量,它们的值被设置在 //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
    }
    

    【讨论】:

      【解决方案2】:

      所以回答你的两个问题:

      1. 但是 PriceCalculator 如何获取 primaryBasePrice、secondaryBasePrice、 tertiaryBasePrice 值进行计算?

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

      1. 否则,为什么要传入构造函数顺序实例引用?为什么 需要吗?

      您需要传递订单实例引用才能调用订单的其他方法。在您给出的示例中,这是一个微不足道的方法,但在其他一些方法中,您可能会调用 Order 的某些方法...

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

      如果您将这些私有方法设置为受包保护,那么您会遇到紧密耦合、功能嫉​​妒和其他问题

      【讨论】:

        猜你喜欢
        • 2021-01-17
        • 2013-10-25
        • 2012-03-12
        • 1970-01-01
        • 2018-11-12
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多