Upgrade to Pro — share decks privately, control downloads, hide ads and more …

«Рефакторинг PHP-кода с применением DDD» — Виталий Чирков, FunCorp

Badoo Tech
February 15, 2020

«Рефакторинг PHP-кода с применением DDD» — Виталий Чирков, FunCorp

«Это доклад про рефакторинг PHP кода с использованием тактических паттернов DDD. Я покажу на примерах, с какими проблемами мы столкнулись, какие приёмы работают.

Цель — продемонстрировать подход к реанимации legacy-кода на основе DDD-примитивов и поделиться своим опытом его применения».

Badoo Tech

February 15, 2020
Tweet

More Decks by Badoo Tech

Other Decks in Programming

Transcript

  1. Рефакторинг PHP-кода
    с применением DDD
    Виталий Чирков, FunCorp

    [email protected]

    2K20

    View Slide

  2. Почему я?
    • 7 лет создаю legacy в FunCorp

    • Использую тактический DDD

    более 5 лет

    • Контрибутил в Doctrine MongoDB ODM 

    ради DDD
    !2

    View Slide

  3. На повестке дня
    • Какие проблемы решаем

    • Что такое DDD и как поможет

    • Проекция общих принципов 

    на PHP реальность
    !3

    View Slide

  4. У вас тут старая лапша 

    разрослась, да еще и с 

    вплетением инфраструктуры
    !4

    View Slide

  5. Проблемы
    • Спагетти-сервисы

    • Один слой fits it all

    • Божественные сущности

    • Анемичные сущности
    !5

    View Slide

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

    View Slide

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

    View Slide

  8. !8

    View Slide

  9. 2003 год
    !9

    View Slide

  10. DDD
    • Техника разработки через
    моделирование предметной области

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

    View Slide

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

    View Slide

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

    • Техники изоляции модели
    !12

    View Slide

  13. Стратегия
    • Взаимодействие моделей

    и команд

    • Определение границ
    контекстов
    !13

    View Slide

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

    View Slide

  15. Основные блоки
    Value Object объект-значение

    Entity сущность

    Repository репозиторий

    Specification спецификация

    Application and domain services сервисы
    !15

    View Slide

  16. Value Object
    • Представляет собой значение
    (идентификатор, цвет, деньги и т.д.)

    • Сравнивается с объектами такого же
    класса по значению

    • Валидирует, порождает себя
    !16

    View Slide

  17. Value Object
    Используем myclabs/php-enum

    с добавленной логикой сравнения и
    __toString.
    !17

    View Slide

  18. Value Object
    !18

    View Slide

  19. Value Object
    !19

    View Slide

  20. Entity
    • Сущность доменной модели

    • Конечный автомат

    • Содержит поведение 

    (не анемична)
    !20

    View Slide

  21. Entity
    !21

    View Slide

  22. Entity
    !22

    View Slide

  23. Repository
    • Имеет семантику коллекции

    • Возвращает валидные сущности

    • Доменно-специфичные методы

    • Изолирует домен от БД
    !23

    View Slide

  24. Repository
    !24

    View Slide

  25. Repository
    !25

    View Slide

  26. Specification
    • Служит для выборки сущностей

    • Можно выбирать по сложным
    критериям

    • Разгружает контракт репозитория

    Interface Segregation Principle
    !26

    View Slide

  27. Specification
    • Может объединяться 

    со спецификациями-друзьями

    • Может содержать порождающую
    логику
    !27

    View Slide

  28. Specification
    !28

    View Slide

  29. Specification
    !29

    View Slide

  30. Domain service
    • Не содержит состояния

    • Работает с сущностями внутри домена

    • Логика, которая не ложится в сущности
    и VO

    • Содержит доменные знания
    !30

    View Slide

  31. Domain service
    !31

    View Slide

  32. Application service
    • Точка входа в домен

    • Выполняет законченную

    бизнес-транзакцию

    • Принимает VO или более сложные DTO

    • Возвращает результат в виде доменных
    объектов или ошибок
    !32

    View Slide

  33. Application service
    • Не содержит состояния

    • Не содержит доменных знаний

    цикломатическая сложность 1

    • Делегирует работу доменным сервисам
    или сущностям
    !33

    View Slide

  34. Application service
    !34

    View Slide

  35. Блоки: итог
    Value Object Entity Repository Specification Service


    factory, event, command, provider, 

    adapter, processor, assembler, etc.
    !35

    View Slide

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

    Слова контекстно-зависимы и слабы в плане
    трактовки
    !36

    View Slide

  37. Проверим язык

    ban

    We need to deactivate user

    delete

    block



    !37

    View Slide

  38. Проверим язык

    ban

    We need to deactivate user

    delete

    block



    !38

    View Slide

  39. Проверим язык


    We need to deactivate user

    after the CRON job is over.





    !39

    View Slide

  40. Проверим язык


    We need to deactivate user

    after rating calculation.




    !40

    View Slide

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

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

    View Slide

  42. План действий
    1. Проверим язык модели

    Слова контекстно-зависимы и слабы в плане
    трактовки

    2. Изолируем модель и применим DDD блоки

    Транспорт и инфраструктура — отдельные слои
    !42

    View Slide


  43. Application

    with DI
    Изолируем модель
    Domain
    Infrastructure

    DB, queue, FS
    Transport

    HTTP, CLI, Queue
    interfaces
    !43

    View Slide

  44. Изолируем модель
    В модели избегаем:

    • MVC контроллеров с HTTP

    • пользовательского интерфейса

    • работы с базой данных, очередями и прочей
    инфраструктурой

    !44

    View Slide

  45. Инфраструктура
    • Интерфейсы для репозиториев

    • Описываем хранение в слое инфраструктуры

    • Оставляем домен чистым

    • Иногда это непросто: спецификации,
    идентификаторы
    !45

    View Slide

  46. Итоги
    • выделили модель предметной
    области

    • провели границы между слоями
    приложения

    • переписали код на блоки DDD

    • научили команду общим терминам
    !46

    View Slide

  47. Источники
    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

    View Slide