Skip to content

PavlentyGood/cell-capture

Repository files navigation

Cell Capture

Демонстрационное backend-приложение на Kotlin с применением Domain-Driven Design, Clean Architecture и Детройтской школы тестирования.
Приложение представляет собой REST API для многопользовательской пошаговой игры.

Содержание

Технологический стек

  • Kotlin
  • Gradle
  • Spring (Web, Data Jdbc, Cloud Stream, Feign)
  • Postgres
  • Kafka
  • Docker, Docker Compose
  • Testcontainers
  • Detekt, JaCoCo
  • ArchUnit

Применяемые подходы и принципы

  • Domain-Driven Design
  • Clean Architecture
  • Детройтская (классическая) школа тестирования
  • Low Coupling & High Cohesion
  • SOLID
  • ООП
  • ФП

Предметная область

Предметной областью является небольшая пошаговая настольная игра.
В одной партии могут принимать участие от 2 игроков.
Игра происходит на поле, разделенном на клетки (примерно 50х50 клеток).
Суть игры в том, чтобы захватить как можно больше клеток на поле.
Перед началом партии игроки собираются вместе и выбирают параметры партии
(размер поля, свои цвета для обозначения захваченных клеток и тд.).
Каждый игрок совершает ход по очереди. Ход состоит из двух фаз.
Первая фаза - бросок кубиков. Игрок делает бросок двумя кубиками.
Выпавшие значения определяют размер области на поле, которую игрок может захватить.
Вторая фаза - процесс захвата.
Игрок определяет область клеток на карте и производит захват.
Затем передается следующему игроку.
Игра продолжается до тех пор, пока на поле остаются области, доступные для захвата.

Event Storming

Ссылка на доску в Miro: https://miro.com/app/board/uXjVKcoerYQ=/

Поддомены

В предметной области выявлено 2 поддомена:

  • Лобби, где игроки собираются вместе и настраивают будущую партию перед игрой
  • Игра, где происходит непосредственный игровой процесс на клеточном поле

Архитектура

Приложение организовано в виде монорепозитория.
Поделено на два микросервиса (ограниченных контекста) и общий модуль (паттерн Shared Kernel).
Каждый микросервис имеет REST API.
Между микросервисами построено событийно-ориентированное взаимодействие посредством Kafka.

Domain-Driven Design

Применяемые стратегические паттерны:

  • Bounded contexts
  • Shared Kernel

Применяемые тактические паттерны:

  • Aggregates
  • Value Objects
  • Domain Events

Clean Architecture

Каждый микросервис построен по принципам Чистой Архитектуры:

  • Трёхслойная структура: адаптеры, юзкейсы, модель предметной области
  • Правило зависимостей: верхнеуровневые слои не зависят от низкоуровненых
  • Модель предметной области инкапсулирована и не зависит от инфраструктуры

Модули

  • lobby - ограниченный контекст, в котором игроки собираются до начала партии и настраивают игру
  • game - ограниченный контекст, где происходит сам игровой процесс
  • kernel - общее ядро для двух ограниченных контекстов
  • tests - сквозные тесты

Подмодули в каждом ограниченном контексте

  • domain - явно выделенная модель предметной области, построенная по принципам тактического DDD
  • restapi - интерфейсы с REST API
  • app - включает конфигурацию, юзкейсы, входные и выходные адаптеры

Диаграмма компонентов

Исходник диаграммы находится в diagram.puml

diagram image

ADR

Важные решения зафиксированы в ADR.md

Сборка ограниченных контекстов

# команды даны на примере ограниченного контекста game

# собрать модуль
gradle :game:app:build

# выполнить тесты
gradle :game:app:test

# проверить стилистику кода
gradle :game:detekt

# собрать docker-образ модуля
gradle :game:app:bootBuildImage

Тесты

Unit-тесты

  • Реализованы в соответствии с детройтской (классической) школой тестирования
  • Покрывают модель предметной области
  • Моки используются только для недетерминированных или инфраструктурных операций

Интеграционные тесты

  • Реализованы в соответствии с детройтской (классической) школой тестирования
  • Каждый интеграционный тест полностью покрывает один сценарий (включает REST API, юзкейс, домен, БД, Kafka)
  • Написаны без использования моков
  • Postgres и Kafka поднимаются с помощью Testcontainers

Сквозные тесты (e2e)

  • Проверяют совместную работу двух ограниченных контекстов (lobby и game)
  • Включают в себя один BDD-сценарий
  • Выполняются с помощью docker-compose с поднятием контейнеров для двух ограниченных контекстов, двух баз данных Postgres и одного экземпляра Kafka
# выполнить сквозные тесты
# это включает в себя сборку с docker-образами модулей lobby и game
gradle :tests:test

Fitness functions (архитектурные тесты)

  • Расположены в пакете fitness в каждом микросервисе
  • Реализованы с помощью ArchUnit
  • Запускаются так же, как и обычные тесты

Качество кода и архитектуры

  • За тестовым покрытием следит JaCoCo
  • Стилистику кода контролирует Detekt
  • Соблюдение подходов Software Design и архитектуры обеспечивает ArchUnit

Референсные проекты

Источником вдохновения и примерами для реализации данного репозитория послужили следующие проекты:

Дальнейшие планы

  • Внедрить CQRS
  • Внедрить Event Sourcing
  • Реализовать микросервис "Редактор игровых полей"
  • Внедрить Spec-Driven Development

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages