Инверсия зависимостей - один из принципов SOLID, который лежит в основе построения гексагональной архитектуры приложения. Существует множество статей, которые раскрывают суть принципа и объясняют как его применять. И, возможно, читатель уже знаком с ними. Но в рамках данной статьи будет продемонстрирован подробный разбор "тактических" приемов для успешного использования инверсии зависимостей и, возможно, в этом смысле даже искушенный читатель сможет найти для себя что-то новое. Примеры представлены на языке программирования Java с соответствующим окружением, но при этом для чтения достаточно понимания похожих языков программирования.
Проектирование и рефакторинг *
Реорганизация кода
- Новые
- Лучшие
- Все
- ≥0
- ≥10
- ≥25
- ≥50
- ≥100
Новости
Темные века разработки программного обеспечения
Пару лет назад я работал в SaaS-компании, которая страдала от всех возможных проблем, связанных с разработкой программного обеспечения. Код был настолько сложным, что внесение простых изменений занимало месяцы. Все проектные задачи и границы проекта оценивались только руководителем. Разработчики не понимали, какую проблему они решают. А когда не знаешь, чего ждет заказчик, многое из того, что делаешь, оказывается бесполезным. Команда не знала, что предложить заказчику. Все были очень разочарованы...
Актуален ли еще Solid?
Перевод статьи Роберта Мартина
Недавно я получил письмо:
В течение многих лет проверка понимания принципов SOLID было стандартной частью нашей процедуры приема на работу. Предполагалось, что кандидаты хорошо знакомы с этими принципами. Однако в последнее время один из наших менеджеров, который больше не занимается программированием, усомнился в том, что это разумно. Его аргументы заключались в том, что принцип открытости-закрытости (open–closed principle) больше не очень важен, потому что большая часть кода, который мы пишем, не содержится в больших монолитах, а внесение изменений в небольшие микросервисы безопасно и легко. Принцип подстановки Лисков (Liskov substitution principle) давно устарел, потому что мы не уделяем столько внимания наследованию, как 20 лет назад. Я думаю, нам следует рассмотреть позицию Дэна Норта по SOLID: «Просто напишите простой код».
В ответ я написал следующее письмо:
Принципы SOLID остаются актуальными и сегодня, как и в 90-е годы (и даже до этого). Это потому, что программное обеспечение не сильно изменилось за все эти годы. Оно не сильно изменилось даже с 1945 года, когда Тьюринг написал первые строчки кода для электронного компьютера. Программное обеспечение по-прежнему представляет собой операторы if, циклы while и операторы присваивания - последовательность, выбор и итерацию.
Каждое новое поколение любит думать, что их мир сильно отличается от мира предыдущего поколения. Каждое новое поколение ошибается в этом. Это то, что каждое новое поколение узнает, когда приходит следующее новое поколение, чтобы рассказать им, насколько все изменилось. Итак, давайте рассмотрим принципы один за другим.
Почему принцип программирования на уровне интерфейсов в большинстве случаев ошибочен и приводит к плохой архитектуре
(Disclaimer!) Данная точка зрения не претендует на роль абсолютной истины и является лишь результатом моего опыта, чтения, наблюдений и размышлений.
Думаю многие знают или слышали о принципах и советах в стиле "Программируйте на уровне интерфейсов, а не реализаций". Хотя в теории, данный принцип кажется полезным и его аргументация звучит логично, но при более глубоком анализе оказывается, что предпосылки лежащие в его основе не реалистичны.
В этой короткой статье я хочу высказать точку зрения, почему данный принцип в большинстве случаев является ошибочным, создает лишние проблемы и приводит к плохой архитектуре.
Обработка ошибок в Rust
Одним из факторов, влияющих на надёжность программного обеспечения является способ обрабатывать ошибки, возникающие в процессе выполнения. Создатели Rust не стали повторять популярные методы, а выбрали другой способ, позволяющий описывать и обрабатывать ошибки более явно. В статье мы рассмотрим реализацию данного подхода, а также полезные библиотеки, упрощающие обработку ошибок.
Автоматизация бизнес-процессов своими руками
У нас было: N различных систем, которые обращались друг к другу напрямую; M маркетологов, которые генерировали идеи, хотели проводить разные тесты и часто предлагали подключить какой-нибудь новый сервис; и K менеджеров по продажам, у которых было много рутинной работы.
Все это порождало проблемы по поддержке и ошибки человека.
Решение: автоматизация и инкапсуляция бизнес-процессов. Разработать систему, которая снимет с людей рутину и уменьшит количество ошибок, ускорит работу, которую будет просто поддерживать и масштабировать.
Очевидное, невероятное, корпоративное. Эпизод 1. Проблема воина в команде
Чем отличается воин от солдата? Воин – это индивидуальность, прирожденный военный. Один на один у солдата против воина, в большинстве, нет шанса. Однако, война ведется не отдельными схватками. В масштабах войны, влияние индивидуальных навыков конкретного бойца на исход сражения резко падает.
Чем больше масштаб – тем заметнее становится то, что подготовленный строй солдат действует эффективнее, чем толпа индивидуалистов.
Микро-фронтенд. Обзор архитектуры и рекомендуемые практики
Концепция микро-фронтенда – это микросервисный подход при разработке клиентской части. В настоящее время есть тенденция создавать мощное и функционально насыщенное веб-приложение, расположенное поверх микросервисной архитектуры. Со временем микро-фронтендовая архитектура становится частью приложения, зачастую ее разрабатывает отдельная команда. Эта архитектура растет, ее становится сложно поддерживать. Возникает так называемый «фронтендовый монолит». Для решения этой проблемы была сформулирована концепция микро-фронтендов.
Команда кросс-функциональна и разрабатывает фичи в сквозном исполнении: от пользовательского интерфейса до базы данных. Микро-фронтенд понятнее монолита и не столь громоздкий. Микро-фронтендовая архитектура такого типа призвана разделить все компоненты приложения на категории в зависимости от их бизнес-составляющей, в масштабах всего стека. В таком случае разработчики фронтенда могут рассчитывать на ту же степень гибкости, тестируемости и скорости разработки, какая привычна для команд с бекенда, работающих с микросервисами.
Предметно-ориентированное проектирование (DDD) | Эванс Эрик — обзор книги и рекомендации
В одном романе для того, чтобы подчеркнуть бесспорную красоту и поразительную сексуальность одной из героинь, автор использовал фразу: "She was a such kind of woman, that every man look at twice". Что в литературном переводе можно понять: "Одна была такой женщиной, что каждый мужчина оборачивался ей в след".
И точно такую же фразу я могу применить к бесподобной книге "Предметно-ориентированное проектирование (DDD)" Эванса Эрика. К ней хочется возвращаться каждый раз, когда ты садишься за проектирование системы в незнакомой тебе области. Словно маяк во время шторма, она помогает вести вашу галеру через сложности, чтобы все гребцы увидели землю, а проект увидел успешный старт.
И в этом обзоре, я расскажу, почему, по моему мнению, это MUSH HAVE книга для каждого middle+ разработчика.
YARL: как Яндекс построил распределённый Rate Limiter с нулевым влиянием на время ответа сервисов
Yandex Rate Limiter (далее просто YARL) — это сервис лимитирования нагрузки для распределённых сервисов. Его особенность в том, что он способен работать с миллионами квот, имея при этом очень низкие накладные расходы на проверку квоты. Если совсем кратко, это система распределённых Leaky Bucket'ов, с помощью которых можно ограничивать разные величины, связанные со временем: скорость передачи данных по сети, запросы в секунду и т. п.
Меня зовут Денис Кореневский, я работаю в службе разработки внутреннего хранилища Яндекса, и сегодня я расскажу, как YARL устроен внутри, почему мы вообще написали своё решение и с какими трудностями нам пришлось столкнуться в процессе создания. Добро пожаловать под кат.
Сравнение подходов к реализации распределенных транзакций для микросервисов
Как архитектор-консультант в Red Hat, я имел возможность поработать над множеством проектов для наших клиентов. У каждого из них есть свои особенности, которые, однако, имеют некоторые общие черты. Большинство клиентов хотят знать, как скоординировать запись в несколько систем одновременно. Ответ на этот вопрос обычно включает подробное объяснение двойной записи, распределенных транзакций, современных альтернатив, а также возможных сценариев сбоев и недостатков каждого подхода. Как правило, именно в этот момент заказчик понимает, что разделение монолитного приложения на микросервисы - долгий и сложный путь, обычно требующий компромиссов.
Микросервисы. Не всё то золото, что хайп
Привет, меня зовут Владимир Кустиков, я — архитектор решений в e-Legion. И сегодня я хотел бы рассказать вам про микросервисы.
Наверное, я где-то неправ. А возможно, что у меня просто подгорело. Но в какой-то момент после запроса рассказать о том, в каких проектах я успешно применял микросервисы, мое терпение лопнуло. Ни в каких, понятно?! И это мой персональный повод для гордости. Если вам вдруг стало интересно, что еще может рассказать этот странный безумец с пылающим взором, то у меня есть хорошая новость — ниже о микросервисах будет адаптированный под хаброформат рассказ с картинками. А если нет — смело закрывайте эту статью.
Устойчивость JS-кода к изменениям
Для многих в разработке программ самыми большими проблемами являются (а) их сложность и (б) изменчивость требований. Решение обеих проблем — в декомпозиции целого приложения на более мелкие части (пакеты, модули, классы и функции). Декомпозиция для уменьшения сложности в целом достаточно проста (закон Миллера). Но нужно не просто разбить приложение на части, а сделать эти части устойчивыми к изменениям требований.
В этой публикации я пытаюсь поразмышлять на следующие вопросы: из каких элементов состоит JavaScript-код? каким образом эти элементы взаимодействуют друг с другом? можно ли как-то повысить устойчивость кода к изменениям?
Кровавое легаси: как в одиночку раздробить монолитный сервис и не сойти с ума
Было раннее утро понедельника. Я проснулся раньше времени из-за грохота грома за окном. Подойдя к окну, я увидел, как по небу плыли свинцовые тучи, безжалостно заливая дождем все вокруг. Казалось, что еще чуть-чуть — и наступит второй всемирный потоп. Как будто Вселенная всеми способами пыталась мне намекнуть, что надвигается что-то ужасное, но я даже не представлял, что меня ждет.
Натянув на себя черный плащ, я отправился на работу, прорываясь через ветер и дождь, словно через поле боя. Казалось, что весь мир был против меня. И вот я стоял перед восьмиэтажным, потрепанным жизнью зданием, увешанным ржавыми кондиционерами, словно бородавками. Там находился офис конторы, где я работал.
Лифта рано утром, как всегда, было не дождаться, и я отправился на четвертый этаж по лестнице, любуясь местными красотами и оставляя за собой мокрый шлейф на полу. Я оказался в офисе первым и чувствовал себя королем мира. Сделав себе чай и расположившись в кресле, я принялся доделывать очередную фичу. Казалось, что настали покой и умиротворение.
Команда постепенно стала подтягиваться в офис, и в 10 часов начался ежедневный митап, где мы обменивались статусом о том, что сделали вчера и чем будем заниматься сегодня. После наших отчетов настала пора говорить руководителю, и за окном вдруг отчетливо послышалась стройка, звуки которой пробивались в офис даже сквозь стеклопакеты. Создавалось ощущение, будто дятел сидел у тебя на плече и пытался пробить череп до самого мозга.
В воздухе чувствовалось нарастающее напряжение. Руководитель заговорил, и я почувствовал себя, словно на гильотине.
Произошло действительно страшное: мне предстояло путешествие по удивительному миру legacy-кода в старом корпоративном сервисе.
Безопасная многопоточность в Rust
Представьте ситуацию: вы решили добавить функционал в некоторую сущность (класс, структуру, ...). Для этого вам понадобилось хранить внутри сущности дополнительные данные. Вы добавляете приватные поля, меняете и читаете их внутри методов, интерфейс методов не изменяется, и всё выглядит хорошо. И не просто выглядит, а компилируется, запускается и проходит тесты. Красота... А потом, в один прекрасный день, прод падает. И может быть даже, теряет часть важных данных. Вы с коллегами начинаете искать причину поломки. И оказывается, что та сущность, которую вы дополняли год назад, делится между несколькими потоками, а поля добавленные вами не потокобезопасны и поэтому гонка за доступ к ним в какой-то момент вызывает их повреждение. Неприятно, согласитесь? Хотелось бы иметь инструмент, позволяющий избегать подобных ситуаций. И язык программирования Rust такой инструмент предоставляет.
Архитектура как кот VS Архитектура как кол
Знаете что я больше всего ненавижу? Я люто ненавижу рамки. Ограничения, которые не дают развить мою идею. Вам знакомы эти чувства? Если да, то приглашаю в подкат поговорить.
PlantUML — инструмент продуктового разработчика
Я дико люблю ковыряться в чужом коде. Это одна из моих любимых специализаций. То есть я просто беру чужой код, анализирую его, читаю. Как я читал его раньше: я переводил код в русский язык. Описывал, что происходит по флоу кода, и пытался понять, что там происходит. Эти записи я в дальнейшем использовал как для написания статей в Confluence, так и для общего понимания происходящего.
С одной стороны, решение работающее. С другой, буквально через неделю-две я уже начинал сомневаться, достаточно точно ли я «перевел» с кода на русский язык? И тогда вспомнил про UML-диаграммы. И вместо того, чтобы записывать текст, стал визуализировать его и исписал неимоверное количество тетрадей.
Но в какой-то момент подумал, что хорошо бы перевести все это в электронный вид, чтобы какой-то инкремент оставался. Не фоткать же, например, для документации, свою тетрадь с каракулями. Так я нашел инструмент PlantUML — opensource-решение, которое использует графическую библиотеку graphviz, превращающее код в наглядные схемы.
Давайте вспомним, что такое Unified Modeling Language. Чаще всего в университете UML используется для описания диаграммы классов.
Зачем С++ в Такси? Доклад Яндекса
— Добрый день. Меня зовут Александр Голубев, и сегодня я вам расскажу, зачем C++ появился в Такси.
Когда использовать mocks в юнит-тестировании
Эта статья является переводом материала «When to Mock».
Использование моков в модульном тестировании является спорной темой. Автор оригинала заметил, что на протяжении всей своей карьеры в программировании он сначала перешел от «моков почти для каждой зависимости» к политике «без моков», а затем к «только моки для внешних зависимостей».
Ни одна из этих практик не является достаточно хорошей. В этой статье Владимир Хориков покажет, какие зависимости следует мокать, а какие использовать как есть в тестах.
7 артефактов проектирования, которые улучшат дизайн
Когда кто-то сегодня говорит о UX, довольно часто он имеет в виду не проектирование пользовательского опыта, а визуальный дизайн. И это объяснимо. Сам по себе интерфейс (UI) уже представляет собой некий конечный продукт, и он прост для понимания.
Но проекты давно перестали быть настолько простыми, что их может делать один человек. Иногда встречаются гении, способные делать всё на хорошем уровне, но это почти такая же редкость, как, например, единороги.
Нам полезно вспомнить, что помогает команде сделать проект вовремя и на должном уровне. Мы попробуем описать ту работу, которая чаще всего скрыта от глаз внешнего наблюдателя, но которая обеспечивает достижение высокого качества проекта. И которая у нас проходит в рамках этапа проектирования.
Вклад авторов
-
SergeyT 594.4 -
m1rko 517.6 -
AloneCoder 504.8 -
marshinov 412.8 -
alizar 374.7 -
fillpackart 349.0 -
tangro 309.0 -
dartmessiah 233.0 -
m36 218.0 -
olegbunin 210.0