Структура проекта - это стратегическое решение, которое должно базироваться на анализе конкретных бизнес‑требований, доступных ресурсов и сроков выполнения проекта!
Я знаю, что есть компании, которые экономят на всем. Тут можно только пытаться объяснять чем это грозит, искать компромиссы и убеждать выделять больше ресурсов. Это как с зубами: если ты их не чистишь, то сколько не лечи, все равно, в конечном итоге будет удаление.
Подходы "Framework agnostic" и "Anti-Corruption Layer" помогают изолировать бизнес логику от внешних зависимостей. Если код написан правильно, те разделен на модули и слои, то вынести кусочек приложения в самостоятельную библиотеку не составит труда. В итоге приложение будет включать в себя множество ваших библиотек с бизнес логикой и через адаптеры связывать их с конкретным фреймворком.
Это прям идеал, к которому надо стремится, но очень дорогой и трудоемкий идеал.
Пример очень удачный :))) Да, фреймворк - это шасси. Бизнес ставит вам задачу сделать кузов. Вы смотрите на рынок выбираете самое популярное шасси, НО чтобы не завязываться на одного производителя делаете кузов не под конкретное шасси, а через адаптер. Через год приходят санкции и запчасти на шасси заканчиваются. Понимая, что бизнес может встать, вы покупаете другое шасси и делаете для него адаптер. И планово переносите кузов на новое шасси. Так что шасси можно менять :))
На практике понятие "framework agnostic" можно применить только к отдельным программным компонентам.
Фреймворк - это просто инструмент. Его можно заменить, тут больше вопрос целесообразности этих действий.
Замена шасси в самосвале не будет выглядеть невозможной, если самосвал спроектирован модульно. Например, вы делаете кабину и к ней есть набор адаптеров для разных вид шасси, у кузова тоже есть свои адаптеры для крепления и т.д.
«проверка доступности» — такая же деталь, которая, наверное, имеет значение только для балансировки трафика.
Не только для балансировки, не всегда пользователи сразу сигнализируют об ошибке. Часто просто уходят с негативом. И даже когда они придут и скажут про ошибку, всегда приятнее им ответить: "наша система мониторинга уже сообщила о проблеме, мы сейчас с ней разбираемся и скоро всё исправим."
насколько эта структура поменяется, например, при смене фреймворка с Laravel на Symfony? Придётся ли переписывать что-то, кроме «клея» между бизнес-логикой и фреймворком? И, наверное, самый важный вопрос: как такая структура защищает от «прикипания» к конкретному фреймворку?
Я пробовал применить это к Симфони, всё точно так же и некоторые моменты даже проще чем в Ларе. В целом, защищает от "прикипания", особенно если на все важные места создавать адаптеры и декораторы.
В идеальном мире frameworkagnostic надо было бы создать свой адаптер на Illuminate, в этом есть минус - это дополнительное время на разработку и тестирование. Но так же это и плюс - при смене фреймворка либо самого либо его версии надо будет исправить только адаптер. В общем, надо искать баланс и где-то идти на уступки всей этой чистой идеологии.
Не совсем так и не в протоколе дело, а в том, что один модуль стал меньше знать о другом модуле. Самое банальное, как создать класс. Это другая зона ответственности. Да, есть паттерны, которые помогают решить эту проблему: DI или Фабрика. Но опять же мы навязываем знание о потребителе поставщику данных.
Утрированно: уменьшая связанность, мы уменьшаем у поставщика данных знания, кто эти данные будет использовать.
В рамках Symfony я подобные вещи решал с помощью стандартного сериализатора.
И ни что не мешает его поставить в любой проект «composer require symfony/serializer».
Это не дичь, а использование уже готового инструмента.
Часто, в работе требуется выполнять разные команды с параметрами в зависимости от настроек конкретного окружения. Постоянно вспоминать команды — напрягает, хочется как-то это упростить и автоматизировать.
Это удобно использовать при переключении между ветками проекта: выполнить миграции, подтянуть новые зависимости или запустить установку заново.
Конечно же обертку можно написать на любом языке, но Make уже дает готовый инструмент.
Как пример, список команд в одном наших из проектов:
=== Application ===
make configure — Настройка конфигов
make reinstall — полная переустановка сервиса (сборка контейнера, сброс БД, composer install)
make install — первоначальная установка или обновление сервиса (сборка контейнера, composer install)
make status — статус приложения
make clean — удаление всех файлов, которые созданы во время установки
make cache-clear — прогрев кэша (через приложение) === Tests ===
make app-ok — проверка всего сервиса
make cc — прогон тестов === Docker ===
make up — поднять сервис
make stop — остановить сервис
make down — остановка с удалением контейнера
make php-cli — войти в shell сервиса php
make nginx-cli — войти в shell сервиса nginx
make php-log — stdout сервиса php
make nginx-log — stdout сервиса nginx === DB ===
make migrate — накатка миграций
make remigrate — Очистка БД и выполнение миграций
Да, есть такой нюанс, я об этом писал в статье:
Я знаю, что есть компании, которые экономят на всем. Тут можно только пытаться объяснять чем это грозит, искать компромиссы и убеждать выделять больше ресурсов.
Это как с зубами: если ты их не чистишь, то сколько не лечи, все равно, в конечном итоге будет удаление.
Подходы "Framework agnostic" и "Anti-Corruption Layer" помогают изолировать бизнес логику от внешних зависимостей.
Если код написан правильно, те разделен на модули и слои, то вынести кусочек приложения в самостоятельную библиотеку не составит труда. В итоге приложение будет включать в себя множество ваших библиотек с бизнес логикой и через адаптеры связывать их с конкретным фреймворком.
Это прям идеал, к которому надо стремится, но очень дорогой и трудоемкий идеал.
Пример очень удачный :)))
Да, фреймворк - это шасси. Бизнес ставит вам задачу сделать кузов. Вы смотрите на рынок выбираете самое популярное шасси, НО чтобы не завязываться на одного производителя делаете кузов не под конкретное шасси, а через адаптер.
Через год приходят санкции и запчасти на шасси заканчиваются. Понимая, что бизнес может встать, вы покупаете другое шасси и делаете для него адаптер. И планово переносите кузов на новое шасси. Так что шасси можно менять :))
В статье давал ссылку на Framework Agnostic длиной в 12 лет, там целый проект так живет.
Фреймворк - это просто инструмент. Его можно заменить, тут больше вопрос целесообразности этих действий.
Замена шасси в самосвале не будет выглядеть невозможной, если самосвал спроектирован модульно. Например, вы делаете кабину и к ней есть набор адаптеров для разных вид шасси, у кузова тоже есть свои адаптеры для крепления и т.д.
Не только для балансировки, не всегда пользователи сразу сигнализируют об ошибке. Часто просто уходят с негативом.
И даже когда они придут и скажут про ошибку, всегда приятнее им ответить: "наша система мониторинга уже сообщила о проблеме, мы сейчас с ней разбираемся и скоро всё исправим."
Я пробовал применить это к Симфони, всё точно так же и некоторые моменты даже проще чем в Ларе.
В целом, защищает от "прикипания", особенно если на все важные места создавать адаптеры и декораторы.
В идеальном мире framework agnostic надо было бы создать свой адаптер на
Illuminate,в этом есть минус - это дополнительное время на разработку и тестирование. Но так же это и плюс - при смене фреймворка либо самого либо его версии надо будет исправить только адаптер.В общем, надо искать баланс и где-то идти на уступки всей этой чистой идеологии.
Для паттерна Chain of Responsibility существуют частные случаи ("подпаттерны"), например: Chain, Pipeline, and Middleware.
Более детально можно прочитать в статье https://orangesoft.co/blog/chain-of-responsibility-design-pattern-in-php
За последний год-два очень сильно развился https://yandex.cloud/ru/services/tracker
Не совсем так и не в протоколе дело, а в том, что один модуль стал меньше знать о другом модуле.
Самое банальное, как создать класс. Это другая зона ответственности. Да, есть паттерны, которые помогают решить эту проблему: DI или Фабрика.
Но опять же мы навязываем знание о потребителе поставщику данных.
Утрированно: уменьшая связанность, мы уменьшаем у поставщика данных знания, кто эти данные будет использовать.
Не думали выложить свое решение в открытый доступ?
Например:
И ни что не мешает его поставить в любой проект «composer require symfony/serializer».
Часто, в работе требуется выполнять разные команды с параметрами в зависимости от настроек конкретного окружения. Постоянно вспоминать команды — напрягает, хочется как-то это упростить и автоматизировать.
Это удобно использовать при переключении между ветками проекта: выполнить миграции, подтянуть новые зависимости или запустить установку заново.
Конечно же обертку можно написать на любом языке, но Make уже дает готовый инструмент.
Как пример, список команд в одном наших из проектов:
Confluence — база знаний (ТЗ и его обсуждение)
Jira — управление задачами и ресурсами