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 full-size slide

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

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

    более 5 лет

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

    ради DDD
    !2

    View full-size slide

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

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

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

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

    View full-size slide

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

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

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

    View full-size slide

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

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

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

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  8. 2003 год
    !9

    View full-size slide

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

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

    View full-size slide

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

    View full-size slide

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

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

    View full-size slide

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

    и команд

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

    View full-size slide

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

    View full-size slide

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

    Entity сущность

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

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

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

    View full-size slide

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

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

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

    View full-size slide

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

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

    View full-size slide

  17. Value Object
    !18

    View full-size slide

  18. Value Object
    !19

    View full-size slide

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

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

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

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

    View full-size slide

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

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

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

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

    View full-size slide

  21. Repository
    !24

    View full-size slide

  22. Repository
    !25

    View full-size slide

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

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

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

    Interface Segregation Principle
    !26

    View full-size slide

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

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

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

    View full-size slide

  25. Specification
    !28

    View full-size slide

  26. Specification
    !29

    View full-size slide

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

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

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

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

    View full-size slide

  28. Domain service
    !31

    View full-size slide

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

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

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

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

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

    View full-size slide

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

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

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

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

    View full-size slide

  31. Application service
    !34

    View full-size slide

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


    factory, event, command, provider, 

    adapter, processor, assembler, etc.
    !35

    View full-size slide

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

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

    View full-size slide

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

    ban

    We need to deactivate user

    delete

    block



    !37

    View full-size slide

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

    ban

    We need to deactivate user

    delete

    block



    !38

    View full-size slide

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


    We need to deactivate user

    after the CRON job is over.





    !39

    View full-size slide

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


    We need to deactivate user

    after rating calculation.




    !40

    View full-size slide

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

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

    View full-size slide

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

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

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

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

    View full-size slide


  40. Application

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

    DB, queue, FS
    Transport

    HTTP, CLI, Queue
    interfaces
    !43

    View full-size slide

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

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

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

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

    !44

    View full-size slide

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

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

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

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

    View full-size slide

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

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

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

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

    View full-size slide

  44. Источники
    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 full-size slide