У меня есть класс для импорта продуктов от операции файла CSV, которая требует приблизительно 7 параметров. Это - информация, которая определенно необходима для средства импорта.
Все это параметры имеет то же время жизни. В конце у нас должен быть Неизменный Объект.
Я также боялся перечислять всех их в конструкторе из-за его влияния к удобочитаемости и решил переместить 3 из них к инжекции методов set. Но очевидно это не изящное решение.
Вопросы:
1) Смешивает основанные на конструкторе и основанные на методе set инжекции плохая практика?
2) Как эта конкретная проблема может быть решена?
Я думал о применении, "Представляют Объект параметра" рефакторинг Martin Fowler, но существует проблема с этим.
4 Параметра могут быть перемещены в Объект параметра довольно легко (customerId, спроектированы, languageId и т.д.) - все целые числа.
Другие 3 параметра являются объектом, который я ввожу (он требуется для Ложных модульных тестов).
Не обязательно плохо смешивать впрыск конструктора и впрыск свойства, но это может быть не так уж и часто. В качестве общей стратегии, избегайте Property Injection, так как это гораздо сложнее реализовать правильно (это может показаться контр-интуитивным, но это правда).
Важно понимать, когда использовать каждый шаблон.
Вы никогда не должны применять Property Injection из-за косметики конструктора.
Когда вам требуется слишком много зависимостей, это признак того, что вы можете нарушить принцип Single Responsibility Principle - класс просто пытается сделать слишком много за один раз.
Вместо того, чтобы вводить объект параметра (в противном случае, это хорошее предложение), лучший вариант - инкапсулировать две или более зависимости в агрегирующий сервис , который организует взаимодействие этих зависимостей.
Представьте, что ваш исходный конструктор выглядит следующим образом:
public MyClass(IDep1 dep1, IDep2 dep2, IDep3 dep3, IDep4 dep4, IDep5 dep5)
После применения некоторого анализа, вы выясняете, что в данном случае IDep1, IDep3 и IDep4 будут использоваться вместе определенным образом. Это позволит вам ввести сервис агрегации, который инкапсулирует их следующим образом:
public class AggService : IAggService
{
public AggService(IDep1 dep1, IDep3 dep3, IDep4 dep4)
{
// ...
}
// ...
}
Теперь вы можете переписать исходный конструктор на:
public MyClass(IAggService aggSrvc, IDep2 dep2, IDep5 dep5)
и так далее....
Очень распространено, что агрегирующий сервис оказывается правильной концепцией, и внезапно вы получаете более богатый API, чем тогда, когда вы начинали.