我的问题很简单,但我找不到合适的解决方案。
代码(仅举例):
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 ++)并且不要改变序列
谢谢
答案 0 :(得分: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 :(得分: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容器注入它们。您还明确指定了方法的契约,因此,如果您必须添加新的实现,则可以通过界面了解要实现的内容。
答案 2 :(得分: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;
}
}
答案 3 :(得分: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;
}
}
答案 4 :(得分:0)
您可以创建基类并应用template method设计模式。
示例
请注意,我使用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;