Добро пожаловать в серию статьей «Марсоход», где мы будем использовать следующие практики:
- Monolithic Repositories — MonoRepo (Монолитные репозитории)
- Command/Query Responsibility Segregation — CQRS (Сегрегация ответственности на чтение и запись)
- Event Sourcing — ES (События как источник)
- Test Driven Development — TDD (Разработка через тестирование)
В этой вводной статье мы просто обозначим спецификации нашего марсохода.
Примечание. Этот пример является адаптированной для нужд серии статей версией упражнения, представленного на Dallas Hack Club, который сейчас, к сожалению, лежит.
Но сначала, давайте кратко пройдемся по упомянутым выше терминам.
Monolithic Repositories — MonoRepo (Монолитные репозитории)
Монолитный репозиторий представляет собой единое версионированное хранилище, содержащее множество пакетов, связанных друг с другом, имеющие возможность быть разделенными на собственные репозитории, но по причинам удобства сложенные в одном месте.
Этот подход дает нам следующие преимущества:
- навигация
- управление зависимостями
- удобство настройки
- выполнение тестов
Однако, он также приносит и следующие недостатки:
- нет жесткого разделения между пакетами
- ограничения по масштабированию (размер на диске, пропускная способность)
- отсутствует возможность точечной настройки доступов (пользователь получает все или ничего)
Такие репозитории имеет смысл делать для проектов, которые будут упакованы / выпущены вместе (хотя и самостоятельные репозитории не исключают подобной возможности)
Примечание. Вот несколько ссылок для дополнительного знакомства с монолитными репозиториями:
Command/Query Responsibility Segregation — CQRS (Сегрегация ответственности на чтение и запись)
CQRS — это о разделении логики «записи» и «чтения», и ее можно применять на многих уровнях, например:
- read-only микросервисы и микросервисы на запись
- конечные точки/задачи только для чтения или только для записи
- разделение ваших моделей на две (опять же, только для чтения и только для записи)
Важно отметить, что CQRS также может быть частично применен в рамках проекта: используйте его только когда это действительно имеет смысл.
Примечание. Вот несколько ссылок о CQRS:
- Command / Query Responsibility Segregation
- CQRS
- Adding the R to CQS: some storage options
- Clarified CQRS
- Functional foundation for CQRS / ES
- Messaging Flavours
- Avoiding the Mud
- Do not mistake DDD for CQRS. Yeah but where to start?
- CQRS/ES
- Fighting Bottlenecks with CQRS
Event Sourcing — ES (События как источник)
С ES каждое значимое действие записывается как «событие». Отслеживание таких событий обеспечивает следующие преимущества:
- воспроизведение событий для воссоздания состояния приложения на конкретный момент (откат, повтор, синхронизация)
- анализ последнего пришедшего состояния (сравнение двух вариантов или поиск кто, что и когда сделал)
Как и с CQRS, важно отметить, что ES также может быть применен _частично_ в проекте: используйте его только когда есть необходимость.
ES часто ассоциируется с CQRS, но они могут использоваться и по отдельности.
Примечание. вот несколько ссылок об ES:
- Using logs to build a solid data infrastructure or: why dual writes are a bad idea
- Event Sourcing
- Practical Event Sourcing
- CQRS/ES
- Fighting Bottlenecks with CQRS
- Functional foundation for CQRS / ES
- Meeting the Broadway team — talking DDD, CQRS and event sourcing
Test Driven Development — TDD (Разработка через тестирование)
TDD можно свести к трем шагам:
- создать тест
- написать достаточно кода, чтобы пройти тест (быстрого и грязного, или просто «заставить работать»)
- рефакторинг кода (создание чистого, «правильно работающего»)
Написание тестов до кода заставляет нас задуматься о том, как будущий код использовался бы. Это как писать спецификации, но сразу с тремя целями: проектирование, разработка документации и автоматизированная регрессионная проверка.
Такой подход легко позволяет иметь высокое покрытие кода (хотя, строго говоря, все равно нужно проверять все возможные пути кода, не только успешные).
Примечание. вот несколько ссылок о TDD:
- Straw man TDD
- Coverage!!!
- The Failures of “Intro to TDD”
- TDD, avoid testing implementation details
- Monogamous TDD
- When TDD doesn’t work
- Does TDD really lead to good design?
- TDD is dead, long live testing
- What TDD is and is not
- TDD, where it all went wrong
- TDD and Complexity
- Giving up on TDD
Спецификации
Цель этой серии заключается в создании программного обеспечения марсохода, согласно следующим спецификациям:
Марсоход должен будет сначала приземлиться в заданном положении. Положение состоит из координат (X
и Y
, являющихся целыми числами) и ориентации (строковое значение north
, east
, west
или south
).
После всего этого он сможет ездить с помощью инструкций, таких как move_forward
(сохраняя ориентацию, но двигаясь по оси x
или y
) или turn_left
/turn_right
(сохраняя те же координаты, но изменяя ориентацию).
Время от времени, он будет сообщать текущее местоположение (опять же x
и y
координаты и ориентацию).
Например, ровер может приземлился на 23
, 42
, north
и затем получить инструкции двигаться вперед дважды, затем налево, а затем снова вперед. Когда будут запрошены координаты, он сообщит 22
, 44
, west
.
Декомпозируем задачу
Из приведенных выше спецификаций, можно выявить как минимум три варианта использования:
- Посадка ровера на Марс
- Вождение
- Запрос местоположения
Что дальше
В следующей статье мы создадим проект и его первый пакет: navigation
.
Примечание. Мы будем использовать:
- PHP 7
- Composer
- git
- phpspec и расширение SpecGen
Автор: iGusev