PHPCleanArchitecture — Что нового?

Этот пост является дополнением предыдущего. В нём я расскажу о новых возможностях инструмента (с блэкджеком и шлюпками с примерами и картинками).

b8817531c3dccf602e08bc6ffa1b58d2.jpg

Предисловие

Привет! Рад что ты читаешь это, а еще больше я буду рад, если этот пост окажется для тебя интересным и полезным.

В своём предыдущем посте я представил сообществу инструмент для визуализации и анализа архитектуры php-приложений и автоматизации процесса контроля её качества.

С тех пор прошло не мало времени и мне есть чем поделиться.

Сегодня поговорим о новых возможностях, без которых использование php-clean-architecture в реальных проектах было сильно затруднено (или вообще невозможно).

Содержание

Если бы мне кто-то сказал, что в проекте над которым он трудится продолжительное время (с командой или в одиночку, наверное не важно), нет архитектурных проблем — я бы не поверил. И дело здесь совсем не в компетенции команды или конкретных её членов, а в человеческом факторе.

Человек без ошибки — ошибка природы. (Когда-то давно, в моём детстве, так мне говорил отец).

Мы люди, а людям свойствено ошибаться: разработчик допустил ошибку, ревьюер недоглядел и пропустил запрос на слияние, и вот проблема уже в мастере.

А ты ведь знаешь — архитектурные ошибки коварны. Они могут очень долгое время оставаться незамеченными, а проявляются (по собственному опыту) в самый неподходящий момент.

Автоматизация — самый действенный способ решения многих проблем. Мне кажется, если процесс контроля качества кода/архитектуры в проекте не автоматизирован (средствами различных инструментов, вроде стат. анализаторов и их подобным), в нём просто не может не быть проблем.

Об автоматизации процесса контроля качества архитектуры php-проектов я рассказывал во второй части предыдущего поста. Наглядно и с примерами я показывал, как подключить и начать использовать разработанный мною инструмент php-clean-architecture (далее по статье — phpca). С его помощью можно визуализировать граф зависимости компонентов проекта и контролировать значения метрик качества, описанных Робертом Мартиным в его книге «Чистая архитектура».

Разрешенное состояние проекта

Как оказалось, тогда phpca был хорош при подключении к проектам на начальном этапе. В таких проектах еще нет большого тех. долга, а значит все обнаруженные проблемы можно махом исправить, и дальше уже сам phpca будет бить разработчиков по рукам. Но вот при подключении его к боевому проекту выяснилось, что гибкости для работы с большими проектами, в которых уже накоплен внушительный тех. долг, что разом исправить его за сколь-либо адекватный срок невозможно, сильно не хватает.

Пример: предположим есть проект состоящий из следующих компонентов:

  • domain (сущности, интерфейсы их репозиториев, …)

  • infrastructure (какие-то инфраструктурные классы, типа email и sms сендеров, реализации репозиториев, …)

  • use cases (различные возможные сценарии использования)

  • entry-points (классы запросов и ответов, контроллеры, форматеры и прочее)

Каждый из компонентов содержит 100+ файлов.

Настраивая phpca мы задаём правила:

  • domain не должен иметь исходящих зависимостей

  • use cases может знать только про domain

  • entry-points может знать только про use-cases и domain

  • infrastructure может знать только про domain и use cases

В действительности же:

  • 20 классов из domain каким-либо образом зависят от 17 классов из use cases

  • 32 класса из use case используют 28 сервисов из infrastructure

  • 18 контроллеров из entry-points используют 12 классов из infrastructure

  • и даже сервисы из infrastructure зависят от request-классов из entry-points

(не спрашивай почему так, пример надуманный, но даёт возможность предметно рассмотреть проблему и ее решение)

Что получается? С одной стороны мы не можем быстро решить все обнаруженные проблемы, их слишком много. С другой стороны, если сейчас не задать запрещающие правила для направлений в графе зависимости компонентов, то через время проблем будет еще больше.

Для решения этой проблемы в инструмент была добавлена команда сохранения текущего состояния проекта (настройка доступна в конфигурационном файле phpca-config.php)

// Исключения
'exclusions' => [
    'allowed_state' => [
        'enabled' => true,
        'storage' => __DIR__ . '/phpca-allowed-state.php',
    ],
],

В процессе выполнения, команда vendor/bin/phpca-allow-current-state {?path/to/phpca-config.php} строит и сохраняет нынешний граф зависимости компонентов и их составляющих между собой для его дальнейшего использования.

При истинном значении флага exclusions.allowed_state.enabled, в момент выполнения команд phpca-build-report и phpca-check, ранее сохраненное разрешенное состояние проекта будет учитываться анализатором, и ранее существовавшие несоответствия в графе зависимости компонентов будут игнорироваться.

Таким образом, мы можем взять абсолютно любой проект, с любым количеством проблем, подключить и настроить в нем phpca как нам хочется, выгрузить текущее состояние и сразу запускать его в эксплуатацию. Старые проблемы будут игнорироваться, но новые phpca уже не пропустит. А далее, по мере решения старых проблем, усиливать проверки.

Рекоммендация: Файл для сохранения разрешенного состояния проекта должен быть под управлением системы контроля версий (для того, чтоб у всех членов команды он был един, а еще для возможности частичного построения отчетов или запуска проверок по списку разрешенных путей, но об этом в следующем пункте).

Ограничение работы списком разрешенных путей

В какой-то из дней, сидя на работе и отсматривая одну жирную MR коллеги, я задался вопросом. Запрос на слияние был действительно большим и мне хотелось взглянуть на изменения сверху, без лишних деталей. Тогда я уже использовал phpca в нескольких проектах, но он мог работать только со всей кодовой базой, а я хотел визуализировать лишь ее новую/измененную часть. Ведь это было бы очень удобно, иметь возможность еще на этапе код-ревью, за пару секунд сформировать по измененным файлам отчет без воды и лишних деталей, с визуализацией графа зависимости компонентов и таблиц зависимости их составляющих, и понять какие из этих изменений и чем нарушают установленные правила.

Еще хотелось сделать эту возможность гибкой, чтоб списки разрешенных путей можно было формировать и передавать в команду динамически. Конфигурационный файл для этих целей не подходил чуть больше чем совсем. Так phpca научился работать с переменными окружения.

Рассмотрим пример: ниже расположен общий граф зависимости компонентов php-clean-architecture, построенный командойvendor/bin/phpca-build-reports {?path/to/phpca-config.php} по всей кодовой базе проекта

граф зависимости компонентов php-clean-architectureграф зависимости компонентов php-clean-architecture

Далее рассмотрим детали со страницы отчета по компоненту entry-points

граф зависимости компонента entry-pointsграф зависимости компонента entry-points

(я специально выбрал в качестве примера небольшой компонент небольшого проекта, чтоб всё было максимально наглядно и не возникло путаницы)

На скриншоте видно, что изначально 1класс из entry-points зависит от 4х классов из model.

Далее я внесу некоторые бессмысленные изменения в entry-points и сформирую отчет на основании этих изменений.

не пытайся найти смысл в этих изменениях, ничего не выйдетне пытайся найти смысл в этих изменениях, ничего не выйдет

export PHPCA_ALLOWED_PATHS=`git diff master --name-only` PHPCA_REPORTS_DIR='phpca-reports-by-git-diff'; bin/phpca-build-reports

Общий граф зависимости компонентов и граф зависимостей entry-points теперь выглядят одинаково. (Это происходит из-за того, что текущий отчет отображает данные только из единственного измененного файла, лишние компоненты из основного графа убраны)

граф зависимости компонента entry-points (на основе изменений)граф зависимости компонента entry-points (на основе изменений)внесенные ранее изменения отражены в таблицевнесенные ранее изменения отражены в таблице

На скриншоте видно, что в таблице зависимости составляющих компонента, помимо ранее существовавших теперь стали отражены и вновь внесенные изменения, а лишние компоненты и их составляющие из отчета убраны.

Так было уже почти хорошо, но мне все еще хотелось больше гибкости. Хотелось отбросить больше лишнего и оставить только самое важное. Ведь видеть полный отчет только по измененным файлам — это круто, но иногда было бы полезно видеть по измененным файлам НЕ полный отчет. Зачем мне смотреть список всех зависимостей, пусть даже и только измененных файлов, если я хочу узнать какие зависимости были добавлены в текущей ветке?

Это можно было реализовать дополнив фильтрацию графа по списку разрешенных путей, проверками наличия зависимостей в разрешенном состоянии проекта (из предыдущего пункта статьи).

Ниже я включу в файле конфигурации флаг exclusions.allowed_state.enabled и повторно сформирую отчет на основании git diff текущей ветки с master.

граф зависимостей внесенных в измененных файлахграф зависимостей внесенных в измененных файлах

Теперь граф и таблица зависимостей отображают только те изменения, которые действительно были внесены в измененных файлах. Все остальное из отчета убрано и это как-раз тот результат который мне хотелось получить.

Заключение

Используя описанные выше возможности ты можешь сильно упростить процесс подключения phpca к своему проекту, даже если он активно разрабатывается большой командой и в нем есть много легаси, а также начать использовать инструмент при проведении код-ревью сессий, и таким образом благодаря наглядности облегчить анализ больших запросов на слияние и поиск в них потенциальных архитектурных проблем.

Я искренне рад, что ты дочитал пост до этого места. Спасибо тебе за потраченное время, и я надеюсь что возможность использования phpca и знания приобретенные из этой статьи в дальнейшем сэкономят тебе намного больше времени.

А еще я буду очень рад получить твою обратную связь в ЛС или коментариях.

Доброго времени суток и чистой архитектуры!

© Habrahabr.ru