Итак, у меня есть, может быть, 10 объектов, каждый из которых имеет 1-3 зависимости (что, я думаю, нормально, если речь идет о слабой связи), но также и некоторые настройки, которые можно использовать для определения поведения (время ожидания, размер окна и т. Д.).
Теперь, прежде чем я начал использовать контейнер Inversion of Control, я бы создал фабрику и, возможно, даже простой объект ObjectSettings для каждого из объектов, для которого требуется более 1 установки, чтобы размер конструктора соответствовал рекомендованному параметру «менее 4». размер. Сейчас я использую инверсию управляющего контейнера, и я просто не вижу в этом особого смысла. Конечно, я могу получить конструктор с 7 параметрами, но кого это волнует? В любом случае, все это заполняется IoC.
Я что-то здесь упускаю или это в принципе правильно?
Взаимосвязь между сложностью класса и размером конструктора IoC не приходила мне в голову до прочтения этого вопроса, но мой анализ ниже показывает, что наличие множества аргументов в конструкторе IoC - это запах кода, о котором следует знать при использовании IoC. Наличие цели придерживаться короткого списка аргументов конструктора поможет вам упростить сами классы. Следование принципу единой ответственности поможет вам достичь этой цели.
Я работаю в системе, которая в настоящее время имеет 122 класса, экземпляры которых создаются с использованием среды Spring.NET. Все отношения между этими классами устанавливаются в их конструкторах. По общему признанию, система имеет свою долю неидеального кода, где я нарушил несколько правил. (Но, эй, наши неудачи - это возможность учиться!)
Конструкторы этих классов имеют различное количество аргументов, которые я показываю в таблице ниже.
Number of constructor arguments Number of classes
0 57
1 19
2 25
3 9
4 3
5 1
6 3
7 2
8 2
Классы с нулевыми аргументами являются либо классами конкретной стратегии, либо классами, которые отвечают на события, отправляя данные во внешние системы.
Те, у кого есть 5 или 6 аргументов, несколько не элегантны и могут использовать некоторый рефакторинг для их упрощения.
Четыре класса с 7 или 8 аргументами являются отличными примерами объектов Бога . Они должны быть разбиты, и каждый уже находится в моем списке проблемных мест в системе.
Остальные классы (от 1 до 4 аргументов) (в основном) просто разработаны, просты для понимания и соответствуют принципу единой ответственности .
Привет Джордж,
Прежде всего, каковы зависимости между объектами?
Много отношений "Иса"? Много "хаса" отношений?
Много фанатов? Или разветвление?
Ответ Джорджа: «В основном пытался следовать составу, а не совету по наследству ... почему это важно?»
Поскольку это в основном "хаса", с тобой должно быть все в порядке.
Лучше убедиться, что ваша конструкция (и уничтожение) компонентов выполнена правильно, чтобы предотвратить утечки памяти.
И, если это в C ++, убедитесь, что вы используете виртуальные деструкторы?
Потребность во многих зависимостях (возможно, более 8) может указывать на недостаток дизайна, но в целом я думаю, что нет никаких проблем, пока дизайн является связным.
Кроме того, рассмотрите возможность использования локатора службы или статического шлюза для инфраструктурных задач, таких как ведение журнала и авторизация, вместо того, чтобы загромождать аргументы конструктора.
РЕДАКТИРОВАТЬ: 8, вероятно, слишком много, но я подумал, что будет странный случай для этого. Посмотрев на пост Ли, я согласен, 1-4 обычно хорошо.
Это сложный вопрос, и поэтому я предпочитаю гибридный подход, в котором соответствующие свойства являются изменяемыми, и только неизменяемые свойства и требуемые зависимости без полезного значения по умолчанию являются частью конструктора. Некоторые классы создаются с основами, а затем настраиваются при необходимости через сеттеры.
Все зависит от того, какой контейнер вы использовали для выполнения IOC и какой подход к контейнеру он использует, использует ли он аннотации или файл конфигурации для насыщения объекта, который должен быть выделен. Кроме того, если ваши параметры конструктора - просто простые примитивные типы данных, то это не имеет большого значения; однако, если у вас есть не примитивные типы, то, по моему мнению, вы можете использовать DI на основе свойств, а не DI на основе контрагентов.