Локатор послуг - це, як можна сказати, лише одне з двох зол. "Менший" зводиться до цих чотирьох відмінностей ( принаймні я зараз не можу думати про жодні інші ):
Принцип єдиної відповідальності
Контейнер послуг не порушує Принцип єдиної відповідальності, як це робить Singleton. Сінглтони поєднують створення об’єктів та бізнес-логіку, тоді як Службовий контейнер несе сувору відповідальність за управління життєвим циклом об’єкта вашої програми. У цьому відношенні Контейнер послуг кращий.
Зчеплення
Одиночні коди зазвичай кодуються у вашому додатку через виклики статичного методу, що призводить до жорстких взаємозв’язків та важких для глузування залежностей у коді. SL, з іншого боку, - це лише один клас, і його можна вводити. Отже, хоча всі ваші класифіковані залежатимуть від цього, принаймні, це слабо пов'язана залежність. Отже, якщо ви не застосували ServiceLocator як сам по собі Singleton, це дещо краще і також легше перевірити.
Однак усі класи, які використовують ServiceLocator, тепер залежатимуть від ServiceLocator, який теж є формою зв'язку. Це можна пом'якшити, використовуючи інтерфейс для ServiceLocator, щоб ви не були прив'язані до конкретної реалізації ServiceLocator, але ваші класи залежатимуть від існування якогось Локатора, тоді як невикористання ServiceLocator взагалі значно збільшує повторне використання.
Приховані залежності
Проблема приховування залежностей існує дуже багато. Коли ви просто вводите локатор у ваші споживаючі класи, ви не знаєте ніяких залежностей. Але на відміну від Сінглтона, SL зазвичай створює всі необхідні кулуарні залежності. Отже, коли ви отримуєте Службу, ви не опиняєтесь , як Місько Хевері в прикладі CreditCard , наприклад, вам не доведеться створювати екземпляри всіх депеденцій залежностей вручну.
Отримання залежностей всередині екземпляра також порушує Закон Деметри , який говорить, що не слід копатись у співавторах. Екземпляр повинен говорити лише зі своїми безпосередніми співробітниками. Це проблема як із Singleton, так і з ServiceLocator.
Глобальна держава
Проблема глобального стану також дещо пом'якшена, оскільки при створенні екземпляра нового Службового локатора між тестами також видаляються всі створені раніше екземпляри (якщо ви не допустили помилки та не зберегли їх у статичних атрибутах у SL). Звичайно, це не справедливо для будь-якої глобальної держави в класах, якими керує СЛ.
Також дивіться Фаулера про Службу пошуку локаторів проти введення залежностей для набагато більш глибокого обговорення.
Примітка до вашого оновлення та пов’язана стаття Себастьяна Бергмана про тестування коду, який використовує Singletons : Себастьян жодним чином не припускає, що запропонований обхідний шлях робить використання Singleons меншою проблемою. Це лише один із способів зробити код, який інакше було б неможливо перевірити більш перевіреним. Але це все ще проблематичний код. Насправді він прямо зазначає: "Те, що ти можеш, не означає, що ти повинен".