Действительно ли инверсия зависимостей работает?
Я читал об инверсии зависимостей ('D' в SOLID) и посмотрел несколько примеров здесь.
Однако я не понимаю, как полностью избавиться от зависимости!
Согласно статье отношение Consumer -> Utility можно изменить на Utility -> Consumer, введя контракт / интерфейс в потребительском пакете.
Более того, обратную зависимость можно полностью отделить, переместив контракт / интерфейс в отдельный пакет, такой как Consumer -> Contracts <- Utility.
Теперь с приведенным выше макетом; для потребителя использовать утилиту не должно быть фабрика? Что затем возвращает исходную зависимость следующим образом:
Потребительский -> Завод -> Коммунальный
1 ответ
Если это поможет, я опишу место, где появился Принцип инверсии зависимости, где я работаю.
Я работаю с системой управления контентом - системой, которая хранит изображения и позволяет людям получать их.
Итак, вот как выглядит наш текущий (плохой) код C++:
Retrieve()
// code to initialize a vendor's API
// code to pass in system credentials
// code to clear the vendor's "current workitem list"
// code to pull the document to the current workitem list
// code to get content files from that document
// code to format those files for passing back to the user
В основном, крючки в поставщика слева и справа. И это только одна функция - она одинакова во всем коде.
Теперь представьте, что вам сказали:
"Сумит, мы переходим к новой системе обработки изображений - мы переходим от Vendor ABC к Vendor XYZ. Начните работать над изменением кода для работы с новой системой".
... э-э-э... да... тебе придется переделать весь этот код. В каждой функции, в каждой части вашей программы, которая взаимодействует с этим поставщиком. По сути, шутка Deverdency Inversion гласит: "Вы бы не подлили лампу прямо в электрическую проводку?" Ну, наша группа имеет.
Теперь вот как Deverdency Inversion справляется с этим.
Retrieve()
// Code that initializes an Interface we coded up
// Code that uses that interface, to pull up a doc (which, again, is an interface)
// Code that returns that doc interface's data
... а этот интерфейс?
Interface SimpleExample
void Initialize();
DocExample GetDoc();
Interface DocExample
byte[] GetFileData();
Итак, когда менеджер говорит: "Эй, мы переходим к поставщику XYZ..."
... все, что вам нужно подумать: "Хорошо, мне нужно запрограммировать новый класс, который реализует мой интерфейс" SimpleExample ", и затем я могу подключить его прямо к существующему коду без необходимости изменения какого-либо кода этой программы".!"
Прямо сейчас я работаю над тем, чтобы переписать все это, и позвольте мне сказать вам, что принцип инверсии зависимости уже экономит мне массу времени. Я пишу интерфейс "ContentManagement" (ну, я использую абстрактный класс, но он работает аналогично) - и все, что мне нужно сделать, - это запрограммировать класс, который реализует интерфейс ContentManagement. Тогда я могу иметь такой код:
ContentManagement vendorToUse;
if (some criteria or such)
vendorToUse = instanceOfNewVendor;
else
vendorToUse = instanceOfOldVendor;
vendor.Initialize();
Document doc = vendor.Retrieve(...);
... etc
... пытаться сделать это без DI было бы кошмаром - в основном вам нужно иметь две отдельные версии функции.