Проблема в том, что бизнес-функцию и манипуляции данными мешают в одну кучу. А это — очень большая проблема в реальной жизни. Как и то, что без нормального управления процессом разработки в итоге микросервисы превращаются в кучу грязи, перемешанной и запутанной.
Сервисы — всего лишь инструментарий, который дает нам возможность гибко и быстро менять функционал, добавлять новые фичи и модифицировать старые. Но если при этом утратить понимание, как в целом должна работать система, то получается бардак.
Кстати, когда беседуешь на позицию архитекта, как раз эти вопросы «как сделать все в целом» и поднимают. И за такой ответ «отдадим все на откуп отдельной группе» — вас тупо с улыбкой попросят за дверь. Потому что есть разница между крохотными стартап-проектами и большим продом, который жрет ресурсы и любая ошибка в итоге приносит финансовые потери.
Одна команда полностью должна нести ответственность за всю разработку этой бизнес-функции как на фронтенде, так и в базе данных.
Вот это вообще хорошо…
В большой компании, которая занимается разработкой распределенных систем, нет доступа «каждого встречного-поперечного» к уровню «базы данных». Потому что это — отдельная сущность, отделенная секьюрити, правилами маппинга метаданных и пр.
И в этом случае — все же данные отрабатываются через интерфейсы и эти интерфейсы пишут люди, отвечающие именно за data presentation, transformation и тому подобное. Поэтому от интеграции и коммуникации между различными командами никуда не уйти. Просто API согласовывается на первом этапе, затем для бэтта-тестов выдается макап-сервер с заглушками и две команды одновременно ведут проект, сводя его вместе в финальной точке.
Полностью согласен с мнением, что все эти мантры «программист обязан» используются только для стимулирования дешевой рабочей силы. Как техлид и пр. — могу свои пять копеек вставить.
В обязанности программиста не входит требования «понимание бизнеса». Если ваш программист начал что-то там про бизнес-вижин толкать, стоит гнать его поганой тряпкой. Он не программист, а болтун на чужом месте.
Для ведения проекта уже десятилетиями выработана вполне устойчивая структура, которая обкатана на миллионах проектах, решаюших львиную часть проблем. Но вот как только начинается «оптимизация» по зарплате и затратам на «не приносящие прибыль отделы», так и всплывает пресловутое «должен».
Должен бизнес-аналитик. И техлид, который описанные аналитиком проблемы переводит в четко специфицированное техническое задание. А обязанность программиста — оценить ТЗ, выявить возможные нестыковки (если что не понимает), после чего реализовать код чисто, с максимальной производительностью и покрытием тестами.
Ну, а если вам кто-то из руководства начинает рассказывать про понимание бизнес-процессов, а вы не имеете пресловутых лычек бизнес-аналитика или техлида, то можно смело искать другую работу. Потому что первый звоночек уже прозвенел.
Почитал статью. Посмотрел в зеркало. Почитал статью. Снова посмотрел в зеркало…
Подумал — вроде не я это писал. Но — это же просто моими словами сказано…
И никакого юмора или сарказма. Голимая жизнь…
3 потока, порожденных из основного «цепочкой», затем форма стоит на ShowDialog. Потоки при этом заняты своими делами и кидают сообщения. Первый поток — сообщения от него форма выводит без задержек, остальные потоки — сообщения на форму приходят, выполняется BeginInvoke, после чего — вывода данных нет до момента окончания потока. Все callback с потоков оформлены как асинхронные.
Переписал посылку данных с callback через SynchronizationContext вместо BeginInvoke — все стало отрисовывать.
К сожалению, пример собран на реальном коде. Несколько потоков, порожденных друг из друга и подписка на форме, где идет анализ callbacks и вывод полученных данных. По логам — данные до формы приходят штатно, а с визуализацией через BeginInvoke — проблема. Форма аккуратно складывает информацию у себя, затем ждет окончание работы потока и лишь после этого выводит накопленное.
При работе с контекстом — такого не происходит.
Я смотрел статьи на эту тему, народ предлагает для подобных случаев использовать именно SynchronizationContext.
PS. Повторюсь еще раз — речь именно про WinForm, не WPF.
Создать контрактную библиотеку-враппер для того, чтобы добавить нужный слой проверок — это возможно. Просто нужно представить объем дополнительной работы в этом случае.
На мой взгляд, наиболее простое (не красивое, но простое) решение в данном случае — это использовать «старую нотификацию» для проверки: if () / throw new Exception…
В целом — библиотека контрактов не является обязательным средством разработки, но существенно облегчает жизнь. Поэтому и использовать этот инструмент стоит без излишнего фанатизма, принимая во внимание его ограничения…
Проблема не в том, что я декларирую. Проблема в том, что я использую библиотеки и интерфейсы сторонних разработчиков. Которые не считают нужным гарантировать свою «контрактную» составляющую.
И здесь приходится следовать рекомендациям создателей Contracts — «описывайте контрактные условия в старом стиле».
Фактически, из-за строгой соответствии LSP — я получаю список предупреждений на стыке между моими интерфейсами и чужими.
Сервисы — всего лишь инструментарий, который дает нам возможность гибко и быстро менять функционал, добавлять новые фичи и модифицировать старые. Но если при этом утратить понимание, как в целом должна работать система, то получается бардак.
Кстати, когда беседуешь на позицию архитекта, как раз эти вопросы «как сделать все в целом» и поднимают. И за такой ответ «отдадим все на откуп отдельной группе» — вас тупо с улыбкой попросят за дверь. Потому что есть разница между крохотными стартап-проектами и большим продом, который жрет ресурсы и любая ошибка в итоге приносит финансовые потери.
Вот это вообще хорошо…
В большой компании, которая занимается разработкой распределенных систем, нет доступа «каждого встречного-поперечного» к уровню «базы данных». Потому что это — отдельная сущность, отделенная секьюрити, правилами маппинга метаданных и пр.
И в этом случае — все же данные отрабатываются через интерфейсы и эти интерфейсы пишут люди, отвечающие именно за data presentation, transformation и тому подобное. Поэтому от интеграции и коммуникации между различными командами никуда не уйти. Просто API согласовывается на первом этапе, затем для бэтта-тестов выдается макап-сервер с заглушками и две команды одновременно ведут проект, сводя его вместе в финальной точке.
В обязанности программиста не входит требования «понимание бизнеса». Если ваш программист начал что-то там про бизнес-вижин толкать, стоит гнать его поганой тряпкой. Он не программист, а болтун на чужом месте.
Для ведения проекта уже десятилетиями выработана вполне устойчивая структура, которая обкатана на миллионах проектах, решаюших львиную часть проблем. Но вот как только начинается «оптимизация» по зарплате и затратам на «не приносящие прибыль отделы», так и всплывает пресловутое «должен».
Должен бизнес-аналитик. И техлид, который описанные аналитиком проблемы переводит в четко специфицированное техническое задание. А обязанность программиста — оценить ТЗ, выявить возможные нестыковки (если что не понимает), после чего реализовать код чисто, с максимальной производительностью и покрытием тестами.
Ну, а если вам кто-то из руководства начинает рассказывать про понимание бизнес-процессов, а вы не имеете пресловутых лычек бизнес-аналитика или техлида, то можно смело искать другую работу. Потому что первый звоночек уже прозвенел.
Подумал — вроде не я это писал. Но — это же просто моими словами сказано…
И никакого юмора или сарказма. Голимая жизнь…
Фаулер, Domain Specific Languages
Издания какого года?! :)
3 потока, порожденных из основного «цепочкой», затем форма стоит на ShowDialog. Потоки при этом заняты своими делами и кидают сообщения. Первый поток — сообщения от него форма выводит без задержек, остальные потоки — сообщения на форму приходят, выполняется BeginInvoke, после чего — вывода данных нет до момента окончания потока. Все callback с потоков оформлены как асинхронные.
Переписал посылку данных с callback через SynchronizationContext вместо BeginInvoke — все стало отрисовывать.
При работе с контекстом — такого не происходит.
Я смотрел статьи на эту тему, народ предлагает для подобных случаев использовать именно SynchronizationContext.
PS. Повторюсь еще раз — речь именно про WinForm, не WPF.
На мой взгляд, наиболее простое (не красивое, но простое) решение в данном случае — это использовать «старую нотификацию» для проверки: if () / throw new Exception…
В целом — библиотека контрактов не является обязательным средством разработки, но существенно облегчает жизнь. Поэтому и использовать этот инструмент стоит без излишнего фанатизма, принимая во внимание его ограничения…
PS. Следующая статья про Conract & Interfaces чуть больше.
И здесь приходится следовать рекомендациям создателей Contracts — «описывайте контрактные условия в старом стиле».
Фактически, из-за строгой соответствии LSP — я получаю список предупреждений на стыке между моими интерфейсами и чужими.