0

我的问题是微不足道的,但我找不到合适的解决方案。

代码(仅举例):

public class ToRefact
{
    public int Func1(int i)
    {
        int a = i;
        a++;
        a++;
        a++;

        int b = FuncX2(a); //b = a * 2;

        b++;
        b++;
        b++;
        return a + b;
    }

    public int Func2(int i)
    {
        int a = i;
        a++;
        a++;
        a++;

        int b = FuncX3(a); // b = a * 3;

        b++;
        b++;
        b++;
        return a + b;
    }

    private int FuncX2(int b)
    {
        return b * 2;
    }

    private int FuncX3(int b)
    {
        return b * 3;
    }
}

我们可以看到,func1 和 func2 具有相同的主体,除了代码中间:不同的是 FuncX2 和 FuncX3。但是,我不能做基础抽象类,因为这段代码在中间!我怎样才能做常见的抽象?请不要更改操作(3 次 a++,3 次 b++)并且不要更改顺序

谢谢

4

5 回答 5

2

假设您选择的语言可以将“指针”传递给函数:

public class ToRefact
{
    private int Func(int i, Func<int, int> f)
    {
        int a = i;
        a++;
        a++;
        a++;

        int b = f(a); //b = a * 2;

        b++;
        b++;
        b++;
        return a + b;    
    }

    public int Func1(int i)
    {
        return Func(i, FuncX2);
    }

    public int Func2(int i)
    {
        return Func(i, FuncX3);
    }

    private int FuncX2(int b)
    {
        return b * 2;
    }

    private int FuncX3(int b)
    {
        return b * 3;
    }
}
于 2013-04-17T07:54:20.257 回答
1

您可以使用模板方法(甚至根据实际情况使用策略模式),但在这种简单的情况下,我会这样做:

public class ToRefact
{
    public int Func1(int i)
    {
        int a = FuncAdd3(i);

        int b = FuncX2(a); //b = a * 2;

        b = FuncAdd3(b);
        return a + b; // Or more compact FuncAdd3(i) + FuncAdd3(FuncX2(FuncAdd3(i)))
    }

    public int Func2(int i)
    {
        int a = FuncAdd3(i);

        int b = FuncX3(a); //b = a * 2;

        b = FuncAdd3(b);
        return a + b; // Or more compact FuncAdd3(i) + FuncAdd3(FuncX3(FuncAdd3(i)))
    }

    private int FuncAdd3(int b)
    {
        return b + 2;
    }

    private int FuncX2(int b)
    {
        return b * 2;
    }

    private int FuncX3(int b)
    {
        return b * 3;
    }
}
于 2013-04-17T08:11:59.417 回答
1

或者,您可以创建一个更加模块化和可测试的方法。

创建 ICalculator 接口,如:

 public interface ICalculator
 {
      int Calculate(int a);
 }

以及两个具体的实现

public class CalculatorX : ICalculator
{
      public int Calculate(int a)
      {
          return a * 2;
      }
}

public class CalculatorY : ICalculator
{
      public int Calculate(int a)
      {
          return a * 3;
      }
}

然后你会接受这个作为参数:

public int Func1(ICalculator calculator)
{
    int a = i;
    a++;
    a++;
    a++;

    int b = calculator(a); 

    b++;
    b++;
    b++;
    return a + b;
}

并称它为:

var calculatorX = new CalculatorX();
var result = Func1(calculatorX );

这使得替换实现、模拟它们、甚至使用你最喜欢的 IoC 容器注入它们变得很容易。您还明确指定了方法的协定,因此如果您必须添加新的实现,您可以通过接口知道要实现什么。

于 2013-04-17T08:01:14.677 回答
0
public class ToRefact{
    public int Func1(int i){
        int a = i;
        a = addThree(a);

        int b = FuncX2(a); //b = a * 2;

        b = addThree(b);
        return a + b;
    }

    public int Func2(int i){
        int a = i;
        a = addThree(a);

        int b = FuncX3(a); // b = a * 3;

        b = addThree(b);
        return a + b;
    }

    private int FuncX2(int b){
        return b * 2;
    }

    private int FuncX3(int b){
        return b * 3;
    }

    private int addThree(int x){
        x++;
        x++;
        x++;
        return x;
    }
}
于 2013-04-17T08:05:03.977 回答
0

您可以创建一个基类并应用模板方法设计模式。

例子

请注意,我使用 Delphi,因为这对我来说是最容易从内存中编写的,但是在每种具有虚拟和抽象方法的语言中,意图都是相同的

  TCustomRefact = class(TObject)
  protected
    function Calculate;
    function Multiply(const Value: Integer); virtual; abstract;
  end;

  TRefact1 = class(TCustomRefact )
  protected
    function Multiply(const Value: Integer); override;
  end;

  TRefact2 = class(TCustomRefact )
  protected
    function Multiply(const Value: Integer); override;
  end;
于 2013-04-17T08:05:55.010 回答