удалить дубликат кода, передав метод или что-то? - PullRequest
2 голосов
/ 07 декабря 2011

У меня есть два метода, совершенно похожих друг на друга, но представьте себе:

    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 ]

4 голосов
/ 07 декабря 2011

ApplyVerticalScale и ApplyHor horizontalScale являются совершенно хорошими методами - вам не нужно объединять их в один общедоступный метод ApplyScale «Бог».

Вам следует провести рефакторинг внутренних элементов метода, чтобы один раз вызывать какой-то частный метод ApplyScale (или аналогичный), который содержит Code1 и Code2, причем каждый метод передает все необходимое для применения масштаба в этой конкретной ориентации.

3 голосов
/ 07 декабря 2011

Это один из способов сделать это

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 flag

1 голос
/ 07 декабря 2011

Кажется, что обычным явлением является то, что ваше свойство "Формула" должно получить значение 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();
    // ...
}

И затем каждый раз называйте его по-разному лямбда :

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

Я не вижу реальной выгоды в последнем подходе, поэтому я просто передал бы значение методу (если за вашим вопросом не было чего-то другого, что я не понял).

1 голос
/ 07 декабря 2011

Используя третий метод, вы можете изменить рефакторинг следующим образом:

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

Надеюсь, это поможет.

1 голос
/ 07 декабря 2011

У вас есть много разных вариантов. Какой из них наиболее подходит, зависит от вашего сценария.

  • Поместите код 1 и код 2 в отдельные функции ; это сокращает дублирующийся код до двух строк дублирующего кода.

  • Передать в функцию параметр enum / boolean . На основании этого параметра вы можете проверить, нужно ли вам звонить Method1 или Method2.

  • Используйте абстрактный базовый класс и используйте конкретные реализации для предоставления Formula.

  • Обход делегатов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...