Re[17]: О "наивном" DI и об архитектурном бессилии
От: IQuerist Мухосранск  
Дата: 26.09.16 09:25
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, IQuerist, Вы писали:


IQ>>·>С глобальными переменными?

IQ>>·>Ты так говоришь, как будто это что-то хорошее.
IQ>>В тех проектах на которых работаю я (прямо скажем не больших) в этом нет ничего плохого. В прессе я встречаю не малое количество рекоммендаций по использованию функционального stateless стиля. И мой опыт показывает, что это не пустые слова... Конечно это создает определенные проблемы с согласованностью, но эти проблемы сущая ерунда, по сравнению с теми к которым приводят например попытки реализации наивной доменной модели (DDD). Об этом тоже может напишу пост
·>Ликбез. Ты глубоко заблуждаешься, что просто использование статических методов означает stateless стиль. Это stateless стиль только в том случае, если нет никакого глобального состояния (да вообще никакого состояния нет, ибо _state_less_), а значит результат такого метода зависит _только_ от его аргументов.

Да конечно. Отсутствие глобального состояния важный факт.

·>Да, stateless стиль — благо, но в этом топике я этого не видел, только ламерские Context.Current.


А вы думаете DI фреймворки как-то по другому работают???

·>Кстати, объекты и нестатические методы тоже бывают stateless — иммутабельные классы например.

·>Короче, stateless и static — совершенно независимые непересекающиеся понятия.

Обратного я и не утверждал

·>Да и причём тут DI?


Ну хватит вам уже извиняться за DI

IQ>>·>Если ты пользователь класса, то тебя это не должно заботить, т.к. наличие у тебя объекта означает, что у него можно дёрнуть метод — все зависимости у него будут по определению, т.к. объект сконструирован.

IQ>>·>Если ты разработчк класса, то ты можешь использовать только то, что у тебя есть в конструкторе. Никаких неоднозначностей.
IQ>>Книжный какой-то пример... в любой реализации сущности сколь ни будь сложнее сортировки пузырьком есть дофига нюансов. И что самое паршивое — таких сущностей тоже дофига. Вы можете упомнить все нюансы во всех проектах за 3-6 лет? Или можете описать эти нюансы в названиях методов или комментариях к названиям методов? Имхо это просто невозможно.
·>Я говорю о контроле зависимостей, а не об общей теории всего. Ты задал конкретный вопрос — получил конкретный ответ, но ушел куда-то в абстратные рассуждения, вовращайся скорее к теме, а то скучно становится.

Я показал, что "собирание зависимостей в конструкторе" имеет такую же иллюзорную ценность как и "улучшение тестируемости" решения.

IQ>>Во время работы мне все время приходится читать код и текущего метода, который я модифицирую и многих методов которые он использует и методов, которые используют те методы. Поэтому я честно вообще не понимаю, чем мне особенно может помочь перечисление зависимостей всего класса в конструкторе.

·>Суть в том, что у тебя класс получается более изолированным модулем, который легко понять и проще править независимо, а не просто сборищем малосвязанных методов, которые случайно попали в один файл.

Это все рекламный мусор. Модуль не класс, а то что он вдруг станет сколь ни будь более изолированным, собери я все зависимости в конструкторе, вообще ниоткуда не следует. На rsdn полно топиков о трудности создания api годного качества.

·>Попробуй — понравится, примеры кода я публиковал в этом топике.


Вы знаете, на текущих проектах, у меня неплохо получается поддерживать модульность и изолированность на хорошем уровне и контролировать внешние зависимости без спец. фреймворков.

IQ>>·>Вот есть у тебя UserService.getInstance().serveUser(user) — нужен ли тебе для этого вызова HttpContext.Current? Как узнать?

IQ>>А сколько у вас реализаций UserService.getInstance().serveUser ? У нас одна на 20+ проектов Ей более 6 лет и второй не будет я вас уверяю.
·>Да какая разница? Ну пусть одна (но помни, что она ВНЕЗАПНО в течение 6 лет всяко разно меняется разными людьми). Ответь на вопрос.

Но она практически не меняется, т.к. ее контракт сильно ограничен и определен в рамках конкретного проекта. И все расширения тоже локальны для конкретных проектов. Это просто хороший api для очень конкретной ниши.

Да мне повезло, мне не нужно создавать и поддерживать универсальный user-решатор на все случаи жизни и для всех, всех, всех проектов. Наивные коллеги-разработчики хотели сделать такой, но очевидные последствия необходимости тестирования всех систем (коих три десятка) после любого изменения охладили их неопытный пыл, я считаю это своей заслугой.

IQ>>·>И наоборот. Вот есть у тебя

IQ>>·>
IQ>>·>public void serveUser(User user)
IQ>>·>{
IQ>>·>// как узнать - есть ли тут у меня доступ к HttpContext?
IQ>>·>}
IQ>>·>


IQ>> Ну что-то пример совсем не бей лежачего в BL вообще не должно быть явного использования HttpContext.

·>Ок. Ну пусть не HttpContext, пусть DbContext или как тут выше по топику "Context.Current.Scope.Resolve<IUserManager>". Это что-то изменит?

HttpContextService, DbContextService, CacheContextService, LoggingContextService — имхо как раз первые признаки наивного DI.

IQ>>Все данные должны быть собраны на уровне получения запроса в web controller. А все системные данные текущего пользователя должны находиться в текущем контексте или это будет HttpContext в случае web или CallContext в случае win. Бизнес логика об этом ничего не должна знать.

·>И как это выражается и контролируется на уровне кода?

А как это вообще может быть проконтролировано? Только само-дисциплина и код-ревью.

·>Ты наверное просто пишешь в коде

·>
·>public void serveUser(User user)
·>{
·>// Мамой клянус!!!
·>   doSomething(user, Context.Current.Stuff);
·>}
·>

·>А дальше плагин к компилятору находит все эти комментарии и проверяет?

Что за ужосы??? Какие камменты? ServiceLocator.GetCurrentUserInfo или можно вручную создать SysUserService и дернуть нужный метод.

IQ>>>>Но это же самые любимые техники "наивного DI".

IQ>>·>Это "наивный IoC", DI тут не причём.
IQ>> Да я знаю.
·>Ну и зачем опять терминами жонглируешь?

Это я что ли вспомнил про "Конечно, когда конструктор вызывается через рефлекию — IDE ничем помочь не может. А уж если XML-кофиги вспомнить..."?

IQ>>·>Неужели лучше отдать на откуп Undefined Behaviour инициализации статиков?

IQ>>В простых stateless случаях я не вижу в этом проблемы.
·>Простые случаи ВНЕЗАПНО становятся сложными. Да, в проектах на выброс пиши как хошь — пофиг.

Или десятилетия не становятся. И в данном конкретном случае не станут. Впрочем вы натолкнули меня на мысль, поэтому вот имхо неплохой аргумент за DI — фреймворки будут все более абстрагировать логику в модулях и рано или поздно фокусы со static и local context вроде бы должны перестать работать. Но вот что странно, подобный подход был в ранних application server в конце 90х (не знаю как обстоят дела с azure) но вот мы до сих пор пишем веб приложения в которых доступны и http запросы и static и local context.

·>Но я предпочитаю не участвовать в проектах на выброс.


Ох... видать мало бизнес логики вам пришлось запилить на своем веку... иногда на выброс идут целые проекты, потому что юзеры не смогли/не захотели разбираться в софте, который для них создало начальство и саботировали внедрение.

IQ>>В подходе ряды плюсов — не надо ничего описывать,

·>Это тупо технический долг.

Долг за которым никогда не придут — подарок...

IQ>>не надо изучать нюансы сторонних фреймворков, не надо давать пояснений и ждать подвохов.

·>Для DI не нужны фреймворки, нужны только мозги.

А вот это ведь напрямую связано с темой моего поста Вы вообще с чем не согласны та?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.