通过传递方法或其他东西删除重复的代码?

时间:2011-12-07 12:06:52

标签: c# .net oop

我有两种方法完全相同但只是排成一行 想象一下:

    public void ApplyHorizontalScale(int x, int Y)
    {
        // Code 1
        forecast.Formula = Method1(X, Y);
        // Code 2
    }


    public void ApplyVerticalScale(int x, int Y)
    {
        // Code 1
        forecast.Formula = Method2("Foo");
        // Code 2
    }


    int Method1(int x , int y)
    {
        return x+y;
    }

    int Method2(string s)
    {
        return Foo.Length;
    }

问题是代码1和代码2重复了两次! 我怎么能有这样的东西:

public void ApplyScale(int x, int Y, WhichMethod)
{
        // Code 1
        forecast.Formula = WhichMethod();
        // Code 2
}

请注意,Method1和Method2有不同的签名,其中一个正在访问私有成员。

5 个答案:

答案 0 :(得分:4)

ApplyVerticalScale和ApplyHorizo​​ntalScale是非常好的方法 - 您不需要将它们组合成一个“上帝”ApplyScale公共方法。

您应该重构方法的内部,以调用一次包含Code1和Code2的私有ApplyScale(或类似)方法,每个方法都会传递在特定方向上应用scale所需的任何方法。

答案 1 :(得分:3)

这是一种方法

public void ApplyScale(int x, int Y, bool isHorizontal)
{
    // Code 1
    if(isHorizontal)
    {
       forecast.Formula = Method1(X, Y);
    }
    else
    {
       forecast.Formula = Method2("Foo");
    }
    // Code 2
}

您也可以使用enum代替isHorizontal标志

答案 2 :(得分:1)

你有很多不同的选择。哪一个最合适取决于您的情况。

  • 将代码1和代码2放在单独的函数中;这会将重复代码减少到只有两行重复代码。

  • 将enum / boolean 选项参数传递给该函数。根据此参数,您可以检查是否必须致电Method1Method2

  • 使用抽象基类并使用具体实现来提供Formula

  • 传递代表

答案 3 :(得分:1)

通过引入第三种方法,您可以按如下方式进行重构:

public void ApplyHorizontalScale(int x, int Y) 
{ 
    DoWork(x,y, ()=>Method1(X,Y));
} 


public void ApplyVerticalScale(int x, int Y) 
{ 
    DoWork(x,y, ()=>Method2("Foo"));
} 

private void DoWork(int x, int y, Func<int> action)
{
     // Code 1
     forecast.Formula = action();
     // Code 2
}

int Method1(int x , int y) 
{ 
    return x+y; 
} 

int Method2(string s) 
{ 
    return Foo.Length; 
} 

希望这有帮助。

答案 4 :(得分:1)

似乎常见的是,您的“公式”属性需要获得int值。

在这种情况下,就像这样简单:

public void ApplyScale(int x, int Y, int value)
{
    // ...
    forecast.Formula = value;
    // ...
}

然后每次使用不同的调用它:

ApplyScale(x, y, x + y);
ApplyScale(x, y, Foo.Length);

如果你想懒惰计算这个值,你可以这样做:

public void ApplyScale(int x, int Y, Func<int> formula)
{
    // ...
    forecast.Formula = formula();
    // ...
}

然后每次用不同的 lambda 调用它:

ApplyScale(x, y, () => x + y);
ApplyScale(x, y, () => Foo.Length);

我没有看到后一种方法的真正好处,所以我只是将值传递给方法(除非你的问题背后有其他东西,我不明白)。