Разбивая большой, сплоченный класс - PullRequest
5 голосов
/ 28 февраля 2011

У меня есть класс, который я считаю слишком длинным.Я действительно не знаю, что значит слишком длинный, но это около 2500 строк кода.Тем не менее, во всех методах используется хотя бы одна или несколько переменных, поэтому я думаю, что это довольно согласованно.Я думаю о том, чтобы разбить этот класс на несколько небольших классов, которые будут использовать три одинаковые переменные.Это плохой дизайн или это шаблон?

class MyClass
{
    ...
    MyVar1 myVar1;
    MyVar2 myVar2;

    public void DoStuff()
    {
         ...
         MyPart1 myPart1 = new MyPart1(this,myVar1,myVar2);
         myPart1.DoStuff();

         MyPart2 myPart2 = new MyPart2(this,myVar1,myVar2);
         myPart2.DoStuff();
    }
}

Ответы [ 3 ]

7 голосов
/ 28 февраля 2011

Нельзя сказать, что 2500 строк кода - это слишком много для одного класса.

Однако вы можете сказать, что класс, который используется для 10 различных действий, является довольно монолитным.Некоторые люди здесь говорят, что у каждого класса должна быть только одна функциональность.Эти люди читали бы «10» как двоичный код ...

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

Начните с рассмотрения ваших методов: если в вашем классе есть несколько методов, которые в основном принадлежат одной и той же области (например, XML-I /O или что-то вроде набора функций Play / Pause / Stop / Reset) вы можете создать для них подкласс.
Если все ваши методы находятся на одном уровне друг с другом (то есть противоположны приведенным выше), я бы сказал,Ваш класс не слишком большой.

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

4 голосов
/ 28 февраля 2011

Подумайте «Единственная ответственность» (SR). Могу поспорить, что класс с 2500 строками кода делает как минимум 20 разных вещей, которые можно легко разделить.

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

Так что единственное, что я могу порекомендовать, это начать каннибализировать ваш класс монстров, и позволить дюжинам маленьких чудес с одним ударом увидеть свет :-)

С уважением, Morten

3 голосов
/ 28 февраля 2011

Если части, которые вы разделяете, не несут легко определяемой, разумной единственной ответственности, я бы не разделил ее так. Если вы можете описать подразделенный класс только одной строкой, и эта строка не «используется для управления var1 и var2», вы можете что-то предпринять.

2500 строк тоже не так уж и велики - иногда для того, чтобы что-то сделать, просто требуется много ясного и связного кода.

Редактировать: Есть несколько способов обнаружить что-то подозрительное в классе.

  • Если вы повторяете один и тот же или очень похожий код несколько раз в теле класса, вы можете выделить повторяющуюся часть, делая класс короче (и, возможно, более информативным)
  • Если существуют явные наборы функций-членов, которые используют конкретное подмножество переменных, и они не перекрываются (т.е. функции-члены 1-10 используют var1, функции-члены 2-20 используют var2 и var3), вы можете иметь скрытая двойная ответственность. Найти точно, что это такое и выделить его, может быть нелегко, но, по крайней мере, вы можете понять, на что обратить внимание.
  • Если некоторые функции незначительно отличаются от других функций, интерфейс класса может быть слишком широким. Не могли бы вы сделать то же самое, что и функция-член, вызвав две другие функции-члена? Если это так, рассмотрите возможность удаления избыточной функции-члена, возможно, просто документируйте, как это сделать с другими более основными функциями-членами.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...