Я розумію самі переваги введення залежності. Візьмемо для прикладу Весну. Я також розумію переваги інших функцій Spring, таких як AOP, помічників різних типів і т. Д. Мені просто цікаво, які переваги конфігурації XML, такі як:
<bean id="Mary" class="foo.bar.Female">
<property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
<property name="girlfriend" ref="Mary"/>
</bean>
порівняно зі звичайним старим кодом Java, таким як:
Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);
що простіше налагоджувати, перевіряти час компіляції і його може зрозуміти кожен, хто знає лише Java. Отже, яка головна мета системи введення залежності? (або фрагмент коду, який показує його переваги.)
ОНОВЛЕННЯ:
У разі
IService myService;// ...
public void doSomething() {
myService.fetchData();
}
Як IoC-фреймворк може здогадатися, яку реалізацію myService я хочу ввести, якщо їх більше? Якщо є лише одна реалізація даного інтерфейсу, і я даю контейнеру IoC автоматично вирішити його використовувати, він буде порушений після появи другої реалізації. І якщо навмисно існує лише одна можлива реалізація інтерфейсу, тоді вам не потрібно вводити його.
Було б дуже цікаво побачити невелику частину конфігурації для IoC, яка свідчить про її переваги. Я деякий час використовую Spring та не можу навести такого прикладу. І я можу показати поодинокі рядки, які демонструють переваги сплячки, dwr та інших рамок, якими я користуюся.
ОНОВЛЕННЯ 2:
Я розумію, що конфігурацію IoC можна змінити без перекомпіляції. Це справді така гарна ідея? Я можу зрозуміти, коли хтось хоче змінити облікові дані БД без перекомпіляції - він може бути не розробником. У вашій практиці, як часто хтось інший, крім розробника, змінює конфігурацію IoC? Я думаю, що для розробників немає зусиль перекомпілювати саме цей клас замість зміни конфігурації. А для не розробника ви, мабуть, хочете полегшити його життя та надати простіший файл конфігурації.
ОНОВЛЕННЯ 3:
Зовнішня конфігурація відображення між інтерфейсами та їх конкретними реалізаціями
Що так добре, щоб зробити його розширеним? Ви не робите весь свій код зовнішнім, тоді як напевно можете - просто помістіть його у файл ClassName.java.txt, прочитайте та компілюйте вручну влітку - ого, ви уникли перекомпіляції. Чому слід уникати компіляції ?!
Ви економите час кодування, оскільки надаєте відображення декларативно, а не в процедурному коді
Я розумію, що іноді декларативний підхід економить час. Наприклад, я декларую лише один раз зіставлення між властивістю bean і стовпцем БД і в сплячому режимі використовує це відображення під час завантаження, збереження, побудови SQL на основі HSQL тощо. Тут працює декларативний підхід. У випадку Spring (на моєму прикладі) декларація мала більше рядків і мала таку ж виразність, що і відповідний код. Якщо є приклад, коли така декларація коротша за код - я б хотів її побачити.
Принцип інверсії управління дозволяє провести тестування одиниць, оскільки ви можете замінити реальні реалізації на підроблені (як, наприклад, заміна бази даних SQL на інтерактивну пам'ять)
Я розумію інверсію переваг управління (я вважаю, що модель дизайну, що обговорюється тут, називається залежним введенням, тому що IoC є більш загальним - існує багато видів контролю, і ми інвертуємо лише один з них - контроль ініціалізації). Я запитував, чому комусь взагалі потрібно щось, крім мови програмування, для цього. Я, безумовно, можу замінити реальні реалізації на підроблені, використовуючи код. І цей код буде виражати те саме, що і конфігурація - він просто ініціалізує поля з підробленими значеннями.
mary = new FakeFemale();
Я розумію переваги DI. Я не розумію, які переваги додає зовнішня конфігурація XML порівняно з конфігураційним кодом, який робить те саме. Я не вважаю, що слід уникати компіляції - я збираю щодня і все ще живу. Я думаю, що конфігурація DI - поганий приклад декларативного підходу. Декларація може бути корисною, якщо оголошується один раз AND використовується багато разів різними способами - наприклад, в сплячому режимі cfg, де відображення між властивістю bean та стовпцем DB використовується для збереження, завантаження, побудови пошукових запитів тощо. Конфігурацію весни DI можна легко перекласти на конфігурація коду, як на початку цього питання, чи не може? І він використовується лише для ініціалізації бобів, чи не так? Що означає декларативний підхід тут нічого не додає, чи не так?
Коли я оголошую сплячу карту, я просто даю сплячку деяку інформацію, і вона працює на її основі - я не кажу їй, що робити. У випадку весни моя декларація каже весною, що саме потрібно робити - то чому б це оголосити, чому б не зробити це?
ОСТАННЕ ОНОВЛЕННЯ:
Хлопці, багато відповідей говорять мені про ін'єкцію залежності, яку я знаю, що це добре. Питання полягає в меті конфігурації DI замість ініціалізації коду - я схильний вважати, що ініціалізація коду коротша і зрозуміліша. Єдиною відповіддю, яку я поки що отримав на своє запитання, є те, що він уникає перекомпіляції, коли змінюється конфігурація. Напевно, я повинен поставити ще одне запитання, оскільки для мене це великий секрет, чому слід уникати компіляції в цьому випадку.