Технічний термін для позначення протилежної ін'єкції залежності?


12

Це скоріше номенклатура (технічне написання), а не суто технічне питання. Я намагаюся написати пропозицію щодо рефакторингу (і присвоїти це собі), зосереджена на розширенні ін'єкції залежності у нашій програмі. У той час як ми використовуємо Spring для автоматичного з'єднання бобів, все ще є випадки, коли інстанціюють боби MyClass obj = new MyClass(...), які можна повністю вводити. Я хотів би зробити свою пропозицію використовувати елегантну номенклатуру та посилатись на модель дизайну, протилежну DI, з відповідним терміном.

Чи є "щільне з'єднання" адекватним терміном, який виступає як антонім до DI?


1
Так, з'єднання описує як акт використання явних імен класів в інших класах, так і результуючий стан бази коду.
Кіліан Фот

11
Ні, щільне з'єднання описує лише властивість отриманого коду, а не протилежність DI. Ви можете використовувати DI і все ще має щільне з'єднання з абсолютно різних причин.
Док Браун


@EricKing шоу. +1 до речі.
candied_orange

1
"Відсмоктування залежності" .
SeldomNeedy

Відповіді:


30

Ні. Щільне з'єднання набагато більше, ніж те, з чим має справу ін'єкція залежності.

Ін'єкційна залежність екстерналізує рішення про реалізацію. Це дуже довго розв'язується, але зчеплення - це не просто це.

Хорошим антонімом для введення залежності є важке кодування залежності . Коли ви конструюєте (використовуєте новий або безпосередньо використовуєте якусь фабрику) всередині об'єкта поведінки, ви разом розбили дві різні проблеми. Локатор сервісу допомагає роз’єднати, але залишає вас в поєднанні з самим локатором служби.

З'єднання - це більше, ніж просто розділення конструкції та поведінки. Якщо у мене є 101 метод, який потрібно викликати в якомусь конкретному порядку від класу А до класу В, я міцно поєднаний. Не має значення, наскільки чудово розділені конструкція та поведінка.

З’єднання - це міра взаємозалежності двох об'єктів. Все, що сприяє утрудненню внесення змін в одне, не впливаючи на інше, сприяє зв'язку. У цьому допомагає ін'єкційна залежність, але це не все.


Так, жорстке кодування (залежність), на відміну від введення його (під час виконання) - саме те, що я збирався запропонувати, ви просто були трохи швидшими за мене.
Док Браун

7
@DocBrown Я іноді бажаю, щоб це місце не надавало особливого наголосу на швидкість. Мені хотілося б почути, як ви це сказали.
candied_orange

Хороша відповідь - введення залежності не передбачає роз'єднання. Вважати, що інакше веде вниз погану дорогу
Ant P

1
@CandiedOrange Можливо, хтось повинен запропонувати в мета, щоб відповіді залишалися прихованими протягом певного періоду часу. І / або що голоси приховуються від публічного перегляду Nгодинами ... Або поки не буде обрана відповідь. Я знаю, що я не зовсім об’єктивний, коли одна відповідь вже має 10 голосів, а інші 5 відповідей - жодного!
svidgen

1
@svidgen пошук "мета швидкої зброї на заході". Випуск вже має довгу історію.
candied_orange

6

Строго кажучи, введення залежностей лише реально проти НЕ введення залежності - і тому будь-яка стратегія управління залежністю, яка не є введенням залежності.

[Небажане] з'єднання, хоча і не зовсім ортогональне питання, може виникати або пом'якшуватися будь-яким способом. Вони поєднані з DependencyClass:

public DependencyInjectedConstructor(DependencyClass dep) {
  dep.do();
}

public DependencyLookupConstructor() {
  var dep = new DependencyClass();
  dep.do();
}

DependencyLookupConstructorDependencyClassв цьому випадку пов'язане з певним . Але вони обоє поєднані DependencyClass. Справжнє зло, якщо воно є тут, не є обов'язково з'єднанням, це DependencyLookupConstructorпотрібно змінити, якщо DependencyClassраптом потрібні власні залежності, які вводяться 1 .

Однак цей конструктор / клас ще більш вільно поєднаний:

public DependencyLocatingConstructor() {
  var dep = ServiceLocator.GetMyDoer();
  dep.do();
}

Якщо ви працюєте в C #, вищевикладене дозволить вам ServiceLocatorповернути що- небудь після GetMyDoer()виклику, доки він може, do()що DependencyLocatingConstructorмає do(). Ви отримуєте перевагу перевірки підпису під час компіляції, навіть не підключаючись до повного інтерфейсу 2 .

Отже, виберіть свою отруту.

Але в основному, якщо існує конкретна "протилежність" ін'єкцій залежностей, це було б щось інше в царині "стратегій управління залежностями". Серед інших, якщо ви використовуєте в розмові щось із наведеного нижче, я визнаю це НЕ введенням залежності:

  • Шаблон локатора обслуговування
  • Локатор залежності / Місцезнаходження
  • Побудова прямого об'єкта / залежності
  • Прихована залежність
  • "Не введення залежності"

1. За іронією долі, деякі проблеми, які DI вирішує на більш високих рівнях, є свого роду результатом [перевитрати] використання DI на нижчих рівнях. Я мав задоволення працювати над з непотрібною базою коди складності в усьому , як у результаті розміщення жменьки місць , де ця складність на насправді допомогла ... Я правда упередженого поганому вплив.

2. Використання розташування служби також дозволяє вам легко вказати різні залежності одного типу за їх функціональною роллю від коду виклику , при цьому, як і раніше, значною мірою сприймає спосіб побудови залежності. Припустимо, вам потрібно вирішити Userабо IUserдля різних цілей: Наприклад, Locator.GetAdministrator()проти Locator.GetAuthor()- або будь-якої іншої . Мій код може запитати те, що йому потрібно функціонально, навіть не знаючи, які інтерфейси він підтримує.


2
Порятунком DependencyInjectedConstructor(DependencyClass dep)є те, що DependencyClass може бути інтерфейсом або абстрактним класом. Ось чому мені сумно, що кодери C # використовують префікс інтерфейсу, як в IDependency. Як клієнт, це справді не моя справа, що ця річ у залежності. Поки я не будую цього, все, що я повинен знати, - це як з ним розмовляти. Що це - чиясь проблема.
candied_orange

Маючи на увазі, що DI все ще підключає вас до цього інтерфейсу, і це зовсім не вимагає, щоб DependencyClassце був абстрактний інтерфейс. Потрібно лише, щоб побудова / конфігурація / логіка розташування існувала "десь в іншому місці". ... Ну, і більш доречно в питанні, справа в тому, що DI не є "протилежністю жорсткого зчеплення" :)
svidgen

Насправді ... Я, можливо, трохи вийшов за межі, кажучи, що DI обов'язково з'єднує вас з інтерфейсом, навіть у C #. Хоча я уникав їх у C #, я маю враження, що можу також приймати dynamicпараметри. (Але не varпараметри, якщо пам'ять служить.) Отже, з DI в C #, я думаю, що мені або доведеться кодувати проти інтерфейсу, або мені доведеться повністю відмовитися від перевірки часу компіляції.
svidgen

Об'єкти з'єднані з інтерфейсами. Ви використовуєте ключове слово інтерфейсу чи ні. Ось що таке належний інтерфейс. Все, що ВИ ХАРАЄТЬСЯ. Що ви відкинете - це деталі щодо впровадження та додаткові речі, які вам не потрібні. Ми можемо формалізувати це за допомогою ключового слова інтерфейсу, щоб клієнт сказав світові: "Все, що мені потрібно, це". Але нам не доведеться. Хек, ми можемо робити набирання качок, добре на деяких мовах.
candied_orange

Я не впевнений, що ми в цілому незгодні. Але для уточнення ... Об'єкти внутрішньо пов'язані з власними інтерфейсами, так. Але сам інтерфейс нав'язує зв'язок залежності лише тоді, коли інтерфейс явно названий. У C #, використовуючи dynamicабо varотримуючи об’єкт з локатора, ми нехтуємо інтерфейсом та використовуємо будь-який клас, який може do()те, що вам потрібно, незалежно від того, чи реалізує цей клас якийсь IDoerінтерфейс. Іншими словами, якщо ми маємо A-> B <-C, DI розв'язує A від C, але це вимагає, щоб і A, і C були пов'язані з B, і перешкоджає використанню D, навіть якщо D буде do().
svidgen

2

Я не знаю , що є конкретний, широко поширена термінологія промисловості, але альтернативні варіанти , які приходять на розум , включають в себе внутрішнє виробництво примірника , створення внутрішніх залежностей , локальні залежності , або локально контекстні залежності .


2
мені подобається, instance creationале це недостатньо конкретно. DI створює екземпляри, але за допомогою контролера, а не на рівні програми. можливоinternal instance creation
амфібій

1

Я б пішов з інкапсуляцією залежності . Це виражає, що залежність заблокована, а не відвідування та виїзд знову.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.