Внедрение зависимостей через конструкторы или установщики свойств? - PullRequest
143 голосов
/ 01 октября 2009

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

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

Ответы [ 14 ]

3 голосов
/ 01 октября 2009

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

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

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

1 голос
/ 28 октября 2016

Это старый пост, но если он понадобится в будущем, возможно, он пригодится:

https://github.com/omegamit6zeichen/prinject

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

0 голосов
/ 08 июля 2016

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

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

0 голосов
/ 06 июня 2014

Это зависит от того, как вы хотите реализовать. Я предпочитаю внедрение в конструктор везде, где я чувствую, что значения, которые входят в реализацию, меняются не часто. Например: если стратегия compnay идет с сервером oracle, я настрою значения моего источника данных для соединения bean-компонента, получающего соединения через внедрение конструктора. В противном случае, если мое приложение является продуктом и, скорее всего, оно может подключиться к любой базе данных клиента, я бы реализовал такую ​​конфигурацию базы данных и мультибрендовую реализацию посредством внедрения сеттера. Я только что взял пример, но есть более эффективные способы реализации сценариев, которые я упомянул выше.

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