2013-04-17 42 views
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次++,3次数b ++),但不改变序列

感谢

回答

1
每一种语言相同

你可以使用template method(或甚至strategy pattern取决于实际情况),但在这种简单的情况下,我会做这样的事情:

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; 
    } 
} 
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; 
    } 
} 
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容器注入它们。你也明确地指定了你的方法的契约,所以如果你不得不添加一个新的实现,你就知道该怎么实现,这要归功于接口。

+1

是的,依赖注入!谢谢 – zzfima

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; 
    } 
} 
0

您可以创建基类并应用template method设计模式。

,我用德尔福作为

笔记最简单的方法让我默写但目的是在具有虚拟和抽象方法

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;