Множини, що будують одну реалізацію. DI безнадійно? Використовувати локатор обслуговування?


14

Скажімо, у нас є 1001 клієнт, який будує свої залежності безпосередньо, а не приймає ін'єкції. Переобладнання 1001 не є варіантом на думку нашого начальника. Нам фактично навіть не дозволений доступ до їх джерела, лише файли класу.

Ми повинні зробити "модернізацію" системи, через яку проходять ці 1001 клієнт. Ми можемо рефакторити все, що нам подобається. Залежності є частиною цієї системи. І деякі з цих залежностей ми повинні змінити, щоб мати нову реалізацію.

Що ми хотіли б зробити - це можливість налаштувати різні реалізації залежностей, щоб задовольнити цю кількість клієнтів. На жаль, DI не здається можливим, оскільки клієнти не приймають ін'єкцій з конструкторами або сеттерами.

Варіанти:

1) Refactor - реалізація послуги, яку користуються клієнти, щоб вона зробила те, що потрібно клієнтам зараз. Вибух ми закінчили. Не гнучка. Не складний.

2) Рефактор реалізація, щоб вона делегувала свою роботу ще одній залежності, яку вона набуває через завод. Тепер ми можемо контролювати, яку реалізацію вони всі використовують, переробляючи фабрику.

3) Рефактор реалізації, щоб він делегував свою роботу ще одній залежності, яку він набуває за допомогою сервера-локатора. Тепер ми можемо контролювати, яку реалізацію вони використовують, конфігуруючи сервіс-локатор, який може бути просто hashmapрядком для об'єктів з невеликим кастингом.

4) Щось, про що я ще навіть не думав.

Мета:

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

Клієнти не повинні знати або контролювати реалізацію своїх залежностей, але вони наполягають на їх побудові new. Ми не можемо контролювати, newале ми контролюємо клас, який вони будують.

Моє запитання:

Що я не міг розглянути?


Запитання від Дока Брауна

чи справді вам потрібна можливість налаштування між різними реалізаціями? З якою метою?

Спритність. Багато невідомих. Керівництво хоче потенціалу для змін. Тільки втрачайте залежність від зовнішнього світу. Також тестування.

вам потрібна механіка часу виконання або просто механіка компіляції часу для переключення між різними реалізаціями? Чому?

Механіки часу компіляції, ймовірно, досить. За винятком тестування.

яка деталізація вам потрібна для перемикання між реалізаціями? Все одразу? На модуль (кожен містить групу класів)? За клас?

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

кому потрібно керувати вимикачем? Тільки ваша / ваша команда розробників? Адміністратор? Кожен клієнт самостійно? Або розробники технічного обслуговування коду клієнта? То наскільки легкою / надійною / безглуздою потрібна механіка?

Розробник для тестування. Змінюються адміністратор як зовнішні апаратні залежності. Це потрібно легко перевірити та налаштувати.


Наша мета - показати, що систему можна швидко переробити та модернізувати.


фактичний випадок використання для комутатора реалізації?

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


1
Я не думаю, що ви багато чого досягнете, зберігаючи фабрики чи локатори в глобальному стані. Навіщо турбуватися? Чи збираєтесь ви перевірити клієнтів, які замінюють залежність?
Василевс

Подумайте про використання користувальницького завантажувача класів.
Василевс

Щось із цікавості, що робить ця система?
Прем'єр

Відповіді:


7

Ну, я не впевнений, що я повністю розумію технічні деталі та їх точні відмінності від підтримуваних рішень, але IMHO спочатку потрібно з’ясувати, який тип гнучкості вам справді потрібен.

Питання, які ви повинні задати собі:

  • чи справді вам потрібна можливість налаштування між різними реалізаціями? З якою метою?

  • вам потрібна механіка часу виконання або просто механіка компіляції часу для переключення між різними реалізаціями? Чому?

  • яка деталізація вам потрібна для перемикання між реалізаціями? Все одразу? На модуль (кожен містить групу класів)? За клас?

  • кому потрібно керувати вимикачем? Тільки ваша / ваша команда розробників? Адміністратор? Кожен клієнт самостійно? Або розробники технічного обслуговування коду клієнта? То наскільки легкою / надійною / безглуздою потрібна механіка?

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

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


Гарні запитання! Перегляньте оновлення.
candied_orange

Оновлено фактичний випадок використання.
candied_orange

@CandiedOrange: Я не можу дати тобі рибу, я можу лише спробувати допомогти тобі на риболовлі самостійно :-)
Doc Brown

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

1
@CandiedOrange Не зациклюйтесь на бажанні зробити DI, тому що це "добре" або "краще", ніж будь-що інше. DI - це одне конкретне рішення проблеми (а іноді й декількох). Але, це не завжди є найбільш «підходящим» рішенням. Не закохуйся ... поводийся так, як є. Це інструмент.
svidgen

2

Тільки для того, щоб переконатися, що я все правильно ставлю. У вас є послуга з деяких класів, скажімо, C1,...,Cnі купа клієнтів, які безпосередньо дзвонять new Ci(...). Тому я думаю, що я погоджуюсь із загальною структурою вашого рішення, яка полягає у створенні нової внутрішньої служби з деякими новими класами, D1,...,Dnякі є приємними та сучасними, і вводити їх залежності (дозволяючи такі залежності через стек), а потім переписувати, Ciщоб нічого не робити, крім інстанції та дельгат до Di. Питання в тому, як це зробити, і ви запропонували кілька способів в 2і 3.

Надати подібну пропозицію 2. Ви можете використовувати ін'єкцію залежності у всьому Diі всередині, а потім створити звичайний корінь композиції R(використовуючи рамку, якщо вважаєте це доцільним), який відповідає за збірку графіка об'єкта. Шукайте Rза статичну фабрику і нехай кожен проходить Ciце Diчерез це. Так, наприклад, у вас може бути

public class OldClassI {
    private final NewClassI newImplementation;

    public OldClassI(Object parameter) {
        this.newImplementation = CompositionRoot.getInstance().getNewClassI(parameter);
    }
}

По суті, це ваше рішення 2, але він збирає всі ваші фабрики в одне місце разом з рештою ін'єкції залежності.


Я згоден з цим. Просто не впевнений, як це не те саме, що локатор служби з варіанту 3. Чи очікуєте ви створити новий екземпляр при кожному виклику getInstance()?
candied_orange

@CandiedOrange Це, мабуть, лише зіткнення у використанні, для мене локатор служби - це дуже конкретно щось, що по суті є лише хешмапом від типів до об'єктів, тоді як цей корінь композиції - це лише об’єкт із купою методів, що конструюють інші об’єкти.
проходити

1

Почніть з простих, не фантастичних, сингулярних реалізацій.

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

Якщо вам потрібна "час встановлення", гнучкість (кожна установка клієнта використовує єдину статичну реалізацію), вам все одно не потрібно робити нічого фантазійного. Ви просто пропонуєте різні DLL або SO (або будь-який ваш формат lib). Клієнту просто потрібно поставити потрібний вlib папку ...

Якщо вам потрібна гнучкість виконання, вам просто знадобиться тонкий адаптер і механізм вибору реалізації. Якщо ви використовуєте фабрику, локатор або контейнер IoC, це здебільшого суперечки. Єдині суттєві відмінності між адаптером та локатором: A) Іменування та В) Незалежно від того, що повертається об'єкт є однотонним чи виділеним екземпляром. І велика різниця між контейнером IoC, заводом / локатором, є хто ким дзвонить . (Часто це питання особистих уподобань.)

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