Информация об изменениях

Сообщение О "наивном" DI и об архитектурном бессилии от 27.07.2016 6:40

Изменено 27.07.2016 6:43 IQuerist

О "наивном" DI и об архитектурном бессилии

Никогда я не имел желания холиварить на тему DI, т.к. во всех проектах, где обнаруживалось страстное желание автора использовать DI и над которыми мне приходилось работать, использование DI выглядело как совершенно очевидный антипаттерн и мне всегда было абсолютно не понятно для чего автор тратит время и силы ничего не получая взамен?

Собственно ситуация имхо довольно типичная — мне то "опыт подказывает", а молодежь старательно "набивает шишки", но при этом, я почему-то сходу не нашел ни одного внятного объяснения от популяризаторов DI того, почему наивное использование DI будет провальным. Поэтому я решил таки сформулировать свой вариант

Посмотрим на типичный пример наивного DI:

public class HomeController : Controller

public HomeController(
IBoringItemDataReader,
IBoringItemDataWriter,
BoringItemChildDataReader,
IBoringItemChildDataWriter,
IAppDataJsonConverter,
...
)

Гиперболизируя можно было бы добавить еще IJsonConverter чтобы механизм конвертирования json можно было изменить и что ни будь вроде IDateTimeProvider, работа с датой и временем вряд ли поменяется, но на всякий случай стоит "уменьшить зависимости" .

Посмотрим на реализацию IBoringItemDataReader:

public class BoringItemDataReader : IBoringItemDataReader

и с десяток совершенно очевидных хелперных stateless методов типа:

GetBoringItemById
GetBoringItemByNumber
GetBoringItemByDataInterval
...

Ребята... вот эта низкоуровневая "требуха" это что ли "сервис"? Вот эти все "внутренности наружу" это инкапсуляция и архитектура? Как получилось, что попытка "соблюсти" принцип DIP очевидно вызывает нарушение всех остальных принципов SOLID и на это закрывают глаза? Как можно внедрять "зависимость сервиса" в ситуации, когда разработчик не способен создать сам внедряемый сервис? Проблема тут имхо базовая — разработчик не имеет навыков создания объектной декомпозиции и пытается компенсировать это использованием сложных механизмов, смысла которых он не понимает.

Лично для меня DI изначально был всего лишь удобным механизмом построения "плагинной архитектуры". Часть знакомых уверяла, что DI жизненно необходим для тестирования, но тут ситуация становилась совсем абсурдной, т.к. архитектурное решение (использовать DI) вроде как принималось, но никаких тестов при этом не было и в будущем они никогда не появлялись.

Как-то так... имхо главная начальная проблема DI — неспособность разработчиков создавать объектные декомпозиции. Это ведет к созданию абсолютно неправильной, очень низкоуровневой и хрупкой системы зависимостей нарушающей 4 из 5 принципов SOLID. Пример того, как некоторые пытаются лечить гланды через задний проход. Кстати неплохое название для антипаттерна — Colonoscopy Injection и для всей братии зомбированных шаблонами "наивных архитекторов" — архитект-практолог.
О "наивном" DI и об архитектурном бессилии

Никогда я не имел желания холиварить на тему DI, т.к. во всех проектах, где обнаруживалось страстное желание автора использовать DI и над которыми мне приходилось работать, использование DI выглядело как совершенно очевидный антипаттерн и мне всегда было абсолютно не понятно для чего автор тратит время и силы ничего не получая взамен?

Собственно ситуация имхо довольно типичная — мне то "опыт подказывает", а молодежь старательно "набивает шишки", но при этом, я почему-то сходу не нашел ни одного внятного объяснения от популяризаторов DI того, почему наивное использование DI будет провальным. Поэтому я решил таки сформулировать свой вариант

Посмотрим на типичный пример наивного DI:

public class HomeController : Controller

public HomeController(
IBoringItemDataReader,
IBoringItemDataWriter,
BoringItemChildDataReader,
IBoringItemChildDataWriter,
IAppDataJsonConverter,
...
)

Гиперболизируя можно было бы добавить еще IJsonConverter чтобы механизм конвертирования json можно было изменить и что ни будь вроде IDateTimeProvider, работа с датой и временем вряд ли поменяется, но на всякий случай стоит "уменьшить зависимости" .

Посмотрим на реализацию IBoringItemDataReader:

public class BoringItemDataReader : IBoringItemDataReader

и с десяток совершенно очевидных хелперных stateless методов типа:

GetBoringItemById
GetBoringItemByNumber
GetBoringItemByDataInterval
...

Ребята... вот эта низкоуровневая "требуха" это что ли "сервис"? Вот эти все "внутренности наружу" это инкапсуляция и архитектура? Как получилось, что попытка "соблюсти" принцип DIP очевидно вызывает нарушение всех остальных принципов SOLID и на это закрывают глаза? Как можно внедрять "зависимость сервиса" в ситуации, когда разработчик не способен создать сам внедряемый сервис? Проблема тут имхо базовая — разработчик не имеет навыков создания объектной декомпозиции и пытается компенсировать это использованием сложных механизмов, смысла которых он не понимает.

Лично для меня DI изначально был всего лишь удобным механизмом построения "плагинной архитектуры". Часть знакомых уверяла, что DI жизненно необходим для тестирования, но тут ситуация становилась совсем абсурдной, т.к. архитектурное решение (использовать DI) вроде как принималось, но никаких тестов при этом не было и в будущем они никогда не появлялись.

Как-то так... имхо главная начальная проблема DI — неспособность разработчиков создавать объектные декомпозиции. Это ведет к созданию абсолютно неправильной, очень низкоуровневой и хрупкой системы зависимостей нарушающей 4 из 5 принципов SOLID. Пример того, как некоторые пытаются лечить гланды через задний проход. Кстати неплохое название для антипаттерна — Colonoscopy Injection и для всей братии зомбированных шаблонами "наивных архитекторов" — архитект-проктолог.