Разделить проект Symfony 2?

У нас есть довольно большое веб-приложение Symfony 2, которое имеет множество различных конечных точек и функций:

  • API для данных из нашего старого продукта
  • веб-компоненты для использования в нашем устаревшем продукте
  • API для нашей новой iOS POS
  • API для портала лояльности конечных пользователей
  • веб-интерфейс для портала лояльности конечных пользователей
  • веб-интерфейс для (отдельного) счета конечного пользователя
  • большая админка с настройкой для всего вышеперечисленного

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

Изначально мы выбрали единый подход «приложение + пакет» для простоты программирования, который хорошо послужил нам при разработке всей платформы. К сожалению, основными недостатками являются:

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

Я провел некоторое исследование, чтобы разделить проект Symfony на несколько проектов (каждый со своим GitHub) и использовать SOA для их соединения. Мой личный опыт, связанный с SOA, заключается в том, что это затрудняет полное тестирование и добавляет много накладных расходов при переходе со стандартных форм Symfony 2 (что мне очень нравится).

Я также думал о другом решении, создавая общий пакет с общими сущностями и репозиториями. Это значительно упростило бы тестирование кода и совместное использование общих служб (менеджеров), хотя я также слышал аргументацию против крупных менеджеров. Большим недостатком этого является то, что мы не можем просто использовать doctrine: schema: update затем, потому что совместное использование базы данных и обновление базы данных в проекте с более низкой версией общего пакета удалит поля .. что приведет к потере данных. Также при таком подходе я не смог найти никаких примеров или вариантов использования … что заставляет меня задуматься, не будет ли у него еще много минусов.

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

2

Решение

Хотя я отвечаю на ваш вопрос, довольно сложно найти волшебное решение для ваших проблем. Это не попытка решить все ваши проблемы и не навязать вам их следование. Это не единственно возможное решение, на самом деле это может даже не решить ваши проблемы. Тем не менее, давайте начнем.

Я бы разделил проект на 4 слоя:

  • Уровень представления: Настольные приложения, веб-интерфейсы (независимо от того,
    это php, C #, если он использует Symphony или любой другой фреймворк и третий
    компоненты библиотеки), мобильные приложения, все, что могут видеть конечные пользователи, и
    взаимодействовать с (также известный как GUI). Эти ребята только общаются с
    Приложение / Сервис для запроса чего-либо, например, списка доступных
    продукты, обновите данные где-нибудь, отправьте электронное письмо для клиентов.
    Ключ здесь, они действительно не знают, как и где
    Аппликационный / Сервисный уровень собирается выполнять запрошенные действия.
  • Уровень приложения / сервиса: Я бы отнесся к этому как контроллеры который может получать запросы от уровня представления, а также внешних веб-сервисов. Они похожи на API и будут принимать решение если они должны получить доступ / манипулировать данными через вместилище, или отправлять электронную почту, используя какой-либо SMPT-сервис. Они просто устанавливают связь между GUI или внешними веб-сервисами, которые могут использовать ваши API и уровни Domain / Infra. Тем не менее, они на самом деле не знают, какую службу SMPT они используют, или где и как будут храниться данные (в MySql через Doctrine, в Sql Server через Entity Framework, в базе данных NoSql, в txt-файлах). Слои приложений обычно имеют свои собственные модели (также известные как ViewModels), которые доступны миру и возвращаются запрашивающей стороне (GUI или внешний веб-сервис), представляя часть доменные модели. Такое сопоставление (преобразование классов домена в классы приложения) можно выполнить с помощью таких шаблонов, как Facade и Adapters (также называемые антикоррупционным уровнем), и существует множество пакетов для решения этой проблемы (для C # есть Automapper, для PHP может быть существует что-то тоже). Зачем вам это нужно? Чтобы не показывать весь свой домен миру. Предположим, у вас есть конечные пользователи Invoice и Loyalty, но вы хотите относиться к ним как к одному уникальному домену класса «Пользователь» с соответствующими им свойствами. Вы можете создать классы LoyaltyUser и InvoiceUser в своем приложении, каждый из которых содержит только необходимые для этой цели свойства, а затем использовать эту технику сопоставления для сопоставления класса User домена каждому из них. Следовательно, прикладной уровень обычно содержит правила аутентификации и авторизации, поэтому только конечный пользователь Loyalty будет иметь разрешение на доступ к действиям контроллера, которые будут иметь дело с моделью LoyaltyUser. Внутри одного действия в контроллере вы не должны выбирать разные пути / пути в зависимости от запрашивающей стороны (для мобильных устройств, сделайте это, для веб-сайта, сделайте это). Вместо этого у вас могут быть разные действия для каждого из них, и на уровне презентации будет известно, что они хотят запросить.
  • Уровень домена: Это ваше ядро, содержащее всю бизнес-логику. Это то, что обеспечивает ценность для вашего бизнеса. Контейнер доменного уровня
    модели / классы, представляющие реальные сущности из вашего мира, интерфейсы
    для сервисов и репозиториев. Домен должен быть максимально чистым и
    естественно возможно. Они не могут знать, что просит приложение
    что-то, ни как тип инфра используется. Они просто занимаются бизнесом
    логика. Слой домена не знает, используете ли вы Doctrine или Laravel в качестве ORM, и не является ли приложение php-сайтом, созданным с помощью Symphony, или Android Native App.
  • Инфра-слой: Здесь вы реализуете такие вещи, как база данных, служба SMPT, ведение журнала и другие вещи, которые могут понадобиться вашему приложению.
    Доктрина будет жить здесь. Поэтому вы бы создали хранилище
    классы, реализующие интерфейсы репозитория вашего домена.
    Реализация репозитория использует Doctrine для работы. Эти
    реализации предоставляются на уровне приложений (обычно через
    Внедрение зависимости). Это означает, что прикладной уровень не должен
    знать, если это Doctrine или Laravel, поэтому приложение использует
    Репозиторий (поэтому логика для доступа к базе данных инкапсулирована).

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

Это очень разделено: если вам нужно перейти с Doctrine на Laravel, вам не нужно менять ни домен, ни приложения. Если вам нужно перейти с Symphony на что-либо другое или даже изменить свой веб-сайт с PHP на ASP или Java, ваш домен не нужно менять.

Добавление большего количества слоев, сопоставление объектов, использование DI не должно замедлять запросы, учитывая цену и емкость оборудования в настоящее время, разница во времени практически незаметна. Вы должны приложить усилия, пытаясь улучшить свой домен, который приносит ценность для бизнеса. Разделение слоев улучшает разделение, повышает вероятность того, что часть приложения будет изменена, а другие части — гибче, повысит гибкость масштабирования приложения и упростит тестирование.

1

Другие решения

Рейн, каково было решение, которое ты наконец-то нашел? Вы на самом деле разделили свой проект?

В этой области действительно не хватает информации, я только что нашел одну разумную статью https://ig.nore.me/presentations/2015/04/splitting-a-symfony-project-into-separate-tiers/

0

По вопросам рекламы [email protected]