Этот проект я использую для разных экспериментов. Надеюсь, не запутаетесь :-)
- Домашка (вариант №1): https://github.com/sizovs/awesome-homework-for-java-developers
- Домашка (вариант №2): https://github.com/sizovs/jninja_challenge
- Про API: https://dev.tube/video/NJpQVIZhIYk
- Resisting Complexity (or how to fight -er, -or classes): https://www.youtube.com/watch?v=dfgtKb-VpRk
- Architecting Well-Structured Java Applications: https://www.youtube.com/watch?v=99VFdX1WS7o
- Про модули: https://dev.tube/video/sND1AR7Q_T0
- Method Object
- SOLID (У меня есть по этой теме доклад как раз для джавистов, можете загуглить. Это мой первый публичный доклад, поэтому не судите строго)
- @VisibleForTesting
- Если классы пишем своими ручками, то все что в них есть будет "дергаться" процедурами и объектами, которые используют эти дата классы. Таким образом, coverage будет максимальный и вы не увидите ложных сигналов, что coverage вдруг просел. А вот классы, которые генерирует библиотека Immutable исключить нужно, так как в них есть много вспомогательных методов, которые мы, скорее всего, дергать не будем и, при создании каждой последующей структуры данных coverage будет по-немногу проседать, давая ложные сигналы. Хорошие новости: за нас уже подумали и Jococo вместе с Gradle-ом по умолчанию исключает классы, которые генерируются annotationProcessor-ами :-) Ура!
- Самый простой ответ: микросервисы это, в первую очередь, способ заскейлить инженерную организацию и достичь автономии работы нескольких инженерных команд. Прыгаем от команды. Одна команда – одна система. Когда начинаем толкаться попами – отделяем команду, даем ей отдельный сервис со своим циклом планирования, деплойментов и так далее. То есть я бы прыгал в первую очередь от топологии команд. По этой теме есть шикарная книга – Team Topologies. Она рассказывает фундаментально про Conway's Law, Cognitive Load и важные факторы, которые нужно понимать чтобы принять оптимальное решение: нужен микро-сервис или нет. Во второй день мы немного коснемся (или уже коснулись) темы как систему разрабатывать так, чтобы при необходимости вырвать микро-сервис (или модуль) было максимально просто.
- Для истории: первый раз микро-сервисы "официально" засветились в компании ThoughtWorks, когда им была поставлена задача разработать банк из команды в 150 человек в сжатые сроки – то есть нужно было распараллелить разработку, чтобы попасть в сроки. Все остальные плюшки вроде "можно использовать разные технологии" были выявлены позже, как побочный эффект.
- Sierra (Head First Design Patterns)
- Kent Beck (eXtreme Programmined Explained)
- Fowler (Refactoring)
- Nygard (Release It!)
- Klepmann (Designing Data-Intensive Applications)
- Fowler (Analysis Patterns)
- Fowler (Patterns of Enterprise Application Architecture)
- Eric Evans (DDD). Книга сложная, но очень полезная.
- Vaughn Vernon (Implementing DDD). Был вопрос о том, как решить, куда положить поведение, как лучше дизайнить сущности, организовать зависимости. Простого ответа нет, но эта книга дает некоторые подсказки.
- Java Application Architecture (Kirk K.) – про структурирование софта
- Dank Mono: https://github.com/sizovs/mac/tree/master/fonts
- Тема: https://plugins.jetbrains.com/plugin/8006-material-theme-ui
- Иконки: https://plugins.jetbrains.com/plugin/10044-atom-material-icons
- Доменные объекты могут кидать ивенты. "Event bus" – тот исключительный случай, когда я использую немного статики, чтобы не подавать "event bus" доменному объекту каждый раз, когда он хочет кинуть ивент. Обратите внимание, что юнит-тестирование не пострадало благодаря паттерну Null Object. Пример смотрим вот тут.
- Часто в бизнес-системах класс Client (или Customer) является депенденси-магнитом и, благодаря DDD, имеет свойство жиреть. Помимо паттернов, которые мы рассмотрели, можно пытаться разбить клиента на несколько сущностей. Например: Lead, Customer, NewsSubscriber, Borrower, AccountHolder, и так далее. Каждую сущность можем хранить в пакете соответствующего бизнес саб-домена.
- Есть такой дизайн паттерн, который называется Transactional Outbox. Идея простая: представим, что у вас есть какой-то важный бизнес сервис, который выполняется транзакционно. Вместе с этим сервисом должно произойти и другое важное действие: например, отсылка данных во внешную систему. Но эта отсылка медленная и влияет на время выполнение транзакции. Теоритически, можно отложить выполнение тяжелой задачи закинув ее в очередь типа ActiveMQ, но, во первых, с очередями все не так гладко, а во вторых внедрять внешную очередь для такого простого сценария это жирновато. Решение: использовать свою реляционную базу данных как очередь. Во первых, вы получаете транзакционность. Во вторых – уже даже нативно можно хранить в базе JSON-ы. Пример простейшей реализации Tx Outbox можете посмотреть в классе Scheduler проекта unsuck-java.
- Поиграться с локингом. Смотрите тест BankAccountLockingSpec проекта unsuck-java. Внимание: какие-то тесты flaky :-)