Нужно ли вводить вспомогательный класс для разработки сложного метода? - PullRequest
1 голос
/ 30 марта 2012

обычно, когда я хочу создать сложный метод A, чтобы разбить его на более мелкие части, я получаю вспомогательный класс ClassA и называю его так:

  Public T MethodA()
      {
        ClassA myClass = new ClassA(some parameter);
        return myClass.Output();
      }

  Class ClassA
  {
      T fields...

      Public ClassA(some parameter)
         {
             Initialize(some parameter)
             DoA();
             DoB();
         }

      Public T Output()
         {
             DoC();
         }
      void DoA();
      void DoB();
      ...

  }

так что на самом деле ClassA - это просто обертка огромного метода.Я чувствую, что создание экземпляра для достижения этой цели - пустая трата времени.Должен ли я сделать его статичным?

Какой шаблон дизайна лучше для него?

Ответы [ 7 ]

2 голосов
/ 30 марта 2012

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

  1. Вызывает базу данных
  2. Изменяет записи
  3. Сортирует их
  4. Группирует их в другую структуру

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

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

var myObject = new MyObject();
var results = myObject.DoFunction();

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

0 голосов
/ 12 апреля 2012

Совершенно хорошо, чтобы в конечном итоге получить отдельный класс, но я бы пошел дальше и спросил: «Какую концепцию он представляет»?

Если вы можете найти хорошее название для класса, это указывает на то, что это было что-то скрытое в вашем дизайне, которое действительно хотело «выйти».Давая ему имя и место в дизайне, вы можете лучше говорить об этом, рассуждать об этом и, возможно, даже находить другие варианты использования.Вы сделали вещи более ясными и понятными, и это хорошая вещь .Оттуда вы можете узнать, что исходному классу действительно не нужно знать о деталях реализации нового класса, а заботится только о его интерфейсе .Поздравляем, вы нашли еще одну концепцию в своем дизайне, которую можно использовать для выделения проблем, как концептуально, так и физически.

С точки зрения рефакторинга этот процесс - то, что Майкл Фезерс называет прорасти класс в своей книге "Эффективная работа с устаревшим кодом".Он используется для разделения логики на тестируемые, независимые и понятные фрагменты.

0 голосов
/ 30 марта 2012

обычно, когда я хочу создать сложный метод A

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

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

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

0 голосов
/ 30 марта 2012

На вашем месте я не буду вызывать любые методы в конструкторе . Хорошей практикой программирования является то, что конструктор не должен бросать исключение.

Перед созданием класса я задам себе вопрос. "Я собираюсь использовать методы в некоторых других местах?" Если ответ да, я создам класс. Если нет, я предпочитаю оставить это как деталь реализации и сделать эти Private методы. Потому что это деталь реализации класса.

0 голосов
/ 30 марта 2012

Ответ на самом деле лежит в метке «ориентация объекта».Если вы хотите спроектировать что-то иначе, вы должны поместить методы в класс первичного объекта, над которым работает метод.

То, что вы хотите сделать, это использовать процедурный подход в чисто объектномориентированный язык как C#.Есть несколько возможных способов сделать это:

  • Как уже упоминалось, вы можете создать класс «tool», который содержит методы, которые не связаны с классом объекта.Этот класс инструментов затем предоставляет один или несколько статических методов.Это было бы ближе всего к тому, как бы вы реализовали его на процедурном языке.
  • Если ваша основная проблема заключается в том, что метод слишком велик, чтобы включать его в класс объектов, с которым он должен быть связан, сначала рассмотримразбить метод на более мелкие части, а затем рассмотреть возможность его реализации в качестве метода расширения класса объекта (который может быть определен вне класса).
  • Наконец, если действительно имеет смысл иметь объект,но вы не хотите создавать новый экземпляр каждый раз, когда используете его, вы можете использовать шаблон синглтона, чтобы у класса был только один экземпляр, который доступен через статический метод.

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

0 голосов
/ 30 марта 2012

Использование статического метода в существующем или статическом классе.

public static void Output(param)
0 голосов
/ 30 марта 2012

Ну, если это соответствует критериям Single-Responsibility" S OLID", то это нормально.

Параметры, передаваемые в конструкторе, обычнонеизменяемые свойства / члены класса.

Вы также можете сделать его статическим, но это вызовет жесткую зависимость , что не рекомендуется.

Альтернативой является использование функциональной программирования, котораяопределим его как показано ниже (при условии, что A и B являются типами):

var func = (A a) => return new B();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...