Slide 1

Slide 1 text

Рефакторинг PHP-кода с применением DDD Виталий Чирков, FunCorp [email protected] 2K20

Slide 2

Slide 2 text

Почему я? • 7 лет создаю legacy в FunCorp • Использую тактический DDD
 более 5 лет • Контрибутил в Doctrine MongoDB ODM 
 ради DDD !2

Slide 3

Slide 3 text

На повестке дня • Какие проблемы решаем • Что такое DDD и как поможет • Проекция общих принципов 
 на PHP реальность !3

Slide 4

Slide 4 text

У вас тут старая лапша 
 разрослась, да еще и с 
 вплетением инфраструктуры !4

Slide 5

Slide 5 text

Проблемы • Спагетти-сервисы • Один слой fits it all • Божественные сущности • Анемичные сущности !5

Slide 6

Slide 6 text

А что делать? !6

Slide 7

Slide 7 text

Щас все по DDD распилим! !7

Slide 8

Slide 8 text

!8

Slide 9

Slide 9 text

2003 год !9

Slide 10

Slide 10 text

DDD • Техника разработки через моделирование предметной области • Общий язык (ubiquitous language) — коммуникация для бизнеса и разработки !10

Slide 11

Slide 11 text

DDD тактика стратегия !11

Slide 12

Slide 12 text

Тактика • Набор блоков для строительства модели предметной области • Техники изоляции модели !12

Slide 13

Slide 13 text

Стратегия • Взаимодействие моделей
 и команд • Определение границ контекстов !13

Slide 14

Slide 14 text

DDD тактика стратегия !14

Slide 15

Slide 15 text

Основные блоки Value Object объект-значение
 Entity сущность
 Repository репозиторий
 Specification спецификация
 Application and domain services сервисы !15

Slide 16

Slide 16 text

Value Object • Представляет собой значение (идентификатор, цвет, деньги и т.д.) • Сравнивается с объектами такого же класса по значению • Валидирует, порождает себя !16

Slide 17

Slide 17 text

Value Object Используем myclabs/php-enum
 с добавленной логикой сравнения и __toString. !17

Slide 18

Slide 18 text

Value Object !18

Slide 19

Slide 19 text

Value Object !19

Slide 20

Slide 20 text

Entity • Сущность доменной модели • Конечный автомат • Содержит поведение 
 (не анемична) !20

Slide 21

Slide 21 text

Entity !21

Slide 22

Slide 22 text

Entity !22

Slide 23

Slide 23 text

Repository • Имеет семантику коллекции • Возвращает валидные сущности • Доменно-специфичные методы • Изолирует домен от БД !23

Slide 24

Slide 24 text

Repository !24

Slide 25

Slide 25 text

Repository !25

Slide 26

Slide 26 text

Specification • Служит для выборки сущностей • Можно выбирать по сложным критериям • Разгружает контракт репозитория
 Interface Segregation Principle !26

Slide 27

Slide 27 text

Specification • Может объединяться 
 со спецификациями-друзьями • Может содержать порождающую логику !27

Slide 28

Slide 28 text

Specification !28

Slide 29

Slide 29 text

Specification !29

Slide 30

Slide 30 text

Domain service • Не содержит состояния • Работает с сущностями внутри домена • Логика, которая не ложится в сущности и VO • Содержит доменные знания !30

Slide 31

Slide 31 text

Domain service !31

Slide 32

Slide 32 text

Application service • Точка входа в домен • Выполняет законченную
 бизнес-транзакцию • Принимает VO или более сложные DTO • Возвращает результат в виде доменных объектов или ошибок !32

Slide 33

Slide 33 text

Application service • Не содержит состояния • Не содержит доменных знаний
 цикломатическая сложность 1 • Делегирует работу доменным сервисам или сущностям !33

Slide 34

Slide 34 text

Application service !34

Slide 35

Slide 35 text

Блоки: итог Value Object Entity Repository Specification Service ➕ factory, event, command, provider, 
 adapter, processor, assembler, etc. !35

Slide 36

Slide 36 text

План действий 1. Проверим язык модели
 Слова контекстно-зависимы и слабы в плане трактовки !36

Slide 37

Slide 37 text

Проверим язык 
 ban
 We need to deactivate user
 delete
 block
 
 !37

Slide 38

Slide 38 text

Проверим язык 
 ban
 We need to deactivate user
 delete
 block
 
 
 !38

Slide 39

Slide 39 text

Проверим язык 
 
 We need to deactivate user
 after the CRON job is over.
 
 
 
 !39

Slide 40

Slide 40 text

Проверим язык 
 
 We need to deactivate user
 after rating calculation.
 
 
 
 !40

Slide 41

Slide 41 text

Проверим язык • Все пользовательские сценарии должны быть воспроизводимы на языке предметной области • Взаимодействие сущностей должно быть понятно всем участникам !41

Slide 42

Slide 42 text

План действий 1. Проверим язык модели
 Слова контекстно-зависимы и слабы в плане трактовки 2. Изолируем модель и применим DDD блоки
 Транспорт и инфраструктура — отдельные слои !42

Slide 43

Slide 43 text


 Application
 with DI Изолируем модель Domain Infrastructure
 DB, queue, FS Transport
 HTTP, CLI, Queue interfaces !43

Slide 44

Slide 44 text

Изолируем модель В модели избегаем: • MVC контроллеров с HTTP • пользовательского интерфейса • работы с базой данных, очередями и прочей инфраструктурой !44

Slide 45

Slide 45 text

Инфраструктура • Интерфейсы для репозиториев • Описываем хранение в слое инфраструктуры • Оставляем домен чистым • Иногда это непросто: спецификации, идентификаторы !45

Slide 46

Slide 46 text

Итоги • выделили модель предметной области • провели границы между слоями приложения • переписали код на блоки DDD • научили команду общим терминам !46

Slide 47

Slide 47 text

Источники 1. Domain-Driven Design: Tackling Complexity in the Heart of Software, Eric Evans 2. Implementing Domain-Driven Design, Vaughn Vernon 3. DDD in PHP mailing list http://dddinphp.org/ 4. Mathias Verraes http://verraes.net/ 5. Martin Fowler on DDD !47