Рефакторинг: вложенный класс или отдельные классы? - PullRequest
1 голос
/ 11 августа 2009

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

То, что я собираюсь сделать, это разделить его на отдельные правила, в основном правило, которое проверяет имя человека по фискальному коду, другое по дате рождения и так далее. Для программиста в конце все выглядит примерно так же. Вместо того, чтобы вызывать огромный конструктор правила FiscalCode, он сделает что-то вроде FiscalCode.GetRules(...) и передаст параметры здесь. GetRules(...) затем создаст отдельные правила и передаст их обратно в виде массива. Это совершенно нормально и правильно для нас.

Так много для вашего фона. Теперь мой вопрос заключается в следующем. Класс FiscalCode (который в настоящее время является нашим могущественным бог-классом) имеет множество служебных методов, которые понадобятся большему количеству отдельных «правил-классов», которые я собираюсь создать. Что я знаю, так это то, что мне все равно понадобится класс FiscalCode для выполнения операции GetRules(...) (для программистов это должно быть каким-то образом неизменным, а не для того, чтобы они делали что-то совершенно новое).

У меня есть два варианта:

  1. Создание моих новых классов правил и доступ к общедоступным статическим служебным методам класса FiscalCode
  2. Создать мои новые классы правил как внутренние вложенные классы класса FiscalCode s.t. У меня уже есть доступ к служебным методам (и, следовательно, нет необходимости выставлять свои служебные методы)

У меня уже есть любимый, но я бы хотел сначала услышать мнение некоторых из вас.

Thx

Ответы [ 6 ]

2 голосов
/ 11 августа 2009

Поскольку ваши методы стали «служебными методами», вам нужно сделать их статичными и общедоступными, но, вероятно, вам нужно переименовать ваш FiscalCode в FiscalCodeUtil. Так что будет очевидно, какие методы он содержит.

1 голос
/ 12 августа 2009

Я бы также предложил пересмотреть шаблон спецификации , в котором даны некоторые указания о том, как подходить к этому типу проблемы. В этом посте также приведены некоторые примеры на C #.

Предлагаемый шаблон спецификации направит вас к вашему варианту №1.

0 голосов
/ 11 августа 2009

Я бы пошел с этим так (я не так хорош в ООП, так что возьмите его с крошкой соли):

Классы правил (вложенные в FiscalCode) реализуют интерфейс IRule, предоставляющий методы правил (такие как Validate (), с любым типом возврата, плавающим в вашей лодке). Фискальный код имеет метод AddRule (), который управляет внутренней коллекцией правил и возвращает ссылку на себя для разрешения цепочки методов:

FiscalCode fc = new FiscalCode();
fc.AddRule(new RuleClass1(<params specific to RuleClass1>)
  .AddRule(new RuleClass2(<params specific to RuleClass2>)
  ...

Кроме того, FiscalCode имеет метод Validate (), который выполняет итерацию по каждому из правил Validate () и обрабатывает ошибки.

IMO, это очень удобно для использования и все еще позволяет вложенным классам правил получать доступ к служебным методам FiscalCode.

0 голосов
/ 11 августа 2009

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

0 голосов
/ 11 августа 2009

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

0 голосов
/ 11 августа 2009

Какие зависимости эти служебные методы имеют от класса FiscalCode или классов правил? Есть ли у них государство?

Если нет никаких зависимостей, я бы предложил переместить эти служебные методы в отдельный класс и, если необходимо, вызвать класс FiscalCode или класс правил в эти методы.

Для указанных вами вариантов единственное различие между 1) и 2) состоит в том, видны ли классы правил для классов, которые их не используют. Я не думаю, что это действительно важная цель. Раньше я волновался об этом все время, когда занимался с ++ ... это была пустая трата времени.

...