Рефакторинг большого метода в .NET - PullRequest
8 голосов
/ 09 марта 2010

Если у меня большой метод .NET, я хочу знать, будет ли хорошей практикой разделять его на несколько методов или нет. Мои опасения: 1 - Есть ли смысл создавать метод, если он будет вызван только один раз?
2 - Если я вызываю приватный метод из своего класса, я стараюсь не использовать переменные экземпляра. Это хорошая или плохая практика? Например:

var a, b;
public void TestMe
{
   FirstTest(a,b);
}
private void FirstTest(paramA, paramB)
{
         //code here with passed in parameters
}

//instead of:
private void FirstTest()
{
      //code here with instance variables a,b
}  

edit: заменить глобальный на экземпляр

Ответы [ 4 ]

9 голосов
/ 09 марта 2010

Что касается вашего первого вопроса, то уменьшение сложности метода является достаточной причиной, чтобы разбить большой метод на маленький.Меньшие методы гораздо легче понять, чем один большой метод.Если все сделано правильно, разделив метод на логически согласованные единицы работы, многие маленькие методы предпочтительнее одного большого метода почти во всех случаях.Единственными условиями, в которых это может быть не так, является то, что это влияет на вашу производительность до такой степени, что она более неприемлема с этой точки зрения.

Что касается второго вопроса, как указывает @Jason, вы используете экземплярпеременные не глобальные в вашем классе.Я бы сказал, какая практика предпочтительнее, зависит от контекста метода.Конечно, если метод может быть повторно использован во многих контекстах, только некоторые из которых работают с переменными экземпляра, он должен быть параметризован.Если вы когда-либо используете только переменные экземпляра, вы можете отказаться от использования параметров и рефакторинга по мере необходимости для удобства использования.

В C # я бы также предпочел использовать экземпляры properties сверх поля , чтобы дополнительно отделить свойство от метода, использующего его.

5 голосов
/ 09 марта 2010

1 - есть ли смысл создавать метод, если он будет вызван только один раз?

Да, для этого есть много причин. Читаемость, пожалуй, самая важная. Если вы можете сделать метод более читабельным и обслуживаемым, разбив его на части, то непременно сделайте это.

По моему опыту рефакторинга унаследованного кода, когда метод слишком длинный, есть маленькие кусочки кода, которые появляются снова и снова. Обычно это лучшие места для поиска возможностей рефакторинга. Создание отдельных методов для этих частей может значительно уменьшить длину метода, и, таким образом, greating увеличивает его читабельность.

2 - если я вызываю приватный метод из моего класса я стараюсь не использовать переменные экземпляра. Это хорошо или плохая практика?

Обычно, чем меньше вы можете сделать область видимости переменной, тем лучше. Как и вы, я склонен использовать параметры, когда это возможно. Если у метода есть ссылки только на его собственные параметры, тогда становится намного проще рассуждать о методе, проверять его правильность и правильно его использовать. (И если метод может сделать это и не изменять какое-либо состояние, то это дает вам лот преимуществ обслуживания.)

Если цель метода лучше всего достигается путем манипулирования полями объекта, то это вполне приемлемо, а во многих случаях и недопустимо. Но, как вы указываете, это особенно верно с публичными методами. При рефакторинге большого метода на более мелкие, я редко, если вообще когда-либо, получаю доступ к полям членов непосредственно в новых методах. Это в основном просто для того, чтобы было легче рассуждать о поведении программы.

При рефакторинге таким образом убедитесь, что вы пометили новые методы как static, если они не имеют доступа к каким-либо полям. Это сделает намерение явным.

4 голосов
/ 10 марта 2010

Цитируя Чистый код (отличная книга), метод должен делать одно и только одно. Если вы делаете несколько вещей в методе, то это, вероятно, означает, что вам нужно извлечь эту логику в отдельный метод. Это также облегчает следование коду. Так что я бы сказал

Вопрос 1: Да, разбить его (разделение интересов).

Вопрос 2: В общем, я считаю плохой практикой иметь глобальные переменные, если вам не нужно . Что касается общего вопроса об использовании частного свойства (переменной экземпляра) отдельно от общедоступного метода получения, я не вижу никаких преимуществ при использовании метода получения. Например, рассмотрим:

function someFunc() {
  anotherFunc(this.a, this.b);
}

function anotherFunc(int paramA, int paramB) {
  //do stuff with paramA and paramB
}

против

function someFunc() {
  anotherFunc();
}

function anotherFunc() {
  //do stuff with this.a and this.b
}

В какой-то момент у вас будет для ссылки на переменную экземпляра с помощью this. Так что я не вижу преимущества. В конце концов, вы внутри вашего класса, поэтому у вас есть полный доступ к закрытым членам.

1 голос
/ 09 марта 2010
  1. Если фрагмент кода будет вызываться только один раз, то, скорее всего, нет причины создавать метод в первую очередь. ОДНАКО, с учетом сказанного, если это частный метод и он используется в качестве отдельного компонента функциональности (отдельная задача), то было бы неплохо разделить его. Вы хотели бы сделать это, чтобы избежать использования одного огромного метода. Примером может быть, если я только один раз выполняю поиск по коду кода, я все же захочу разделить этот поиск, потому что поиск - это отдельная часть функциональности. (Это очень плохой пример. Если у кого-то есть лучший пример, пожалуйста, не стесняйтесь редактировать.

  2. Переменная не является TRULY глобальной, если она не доступна во всей системе. С учетом сказанного я настоятельно рекомендую избегать глобальных переменных, потому что это затрудняет отладку и работу с кодом, поскольку переменные имеют чрезвычайно большую область видимости. Вместо этого я бы сосредоточился на том, чтобы иметь больше локализованных переменных и передавать переменные, которые могут понадобиться функции / методу, и возвращать данные, ожидаемые функцией вызова. Таким образом, вы сохраняете свои данные более локализованными, и, в конечном счете, код легче читать и управлять им. Это не относится к частным или общедоступным методам.

...