2017-01-24 9 views
2

Для того, чтобы мое приложение работало, мне нужно регулярно синхронизировать данные из внешней службы (может быть API или простой текстовый файл, но на данный момент это API).ddd - Где должна синхронизироваться с удаленным API?

Поскольку для этого потребуется создать/обновить сразу несколько объектов, мне необходимо создать службу домена. Тем не менее, мне также нужно создать некоторые DTO, которые будут содержать ответ удаленного интерфейса API?

Куда должна идти эта логика? Должен ли я иметь следующую структуру каталогов:

Domain - 
    Model - // my set of entities and repository interfaces are here 
     .... 
    Synchronization - 
     RunSynchronizationService.php // domain service 
Application 
    Synchronization - 
     SynchronizeData.php // application service 
     SynchronizationDataSourceInterface.php // used by application service 
     MySpecificRemoteApiDataSource.php // this implements the interface above 
     SynchronizationDataSourceResponse.php // this would be returned by each call of SynchronizationDataSourceInterface method, and would contain data normalized, but not validated. 
Infrastructure - 
    MyConcreteImplementationOfModelEntityRepository.php 

И когда я хочу, чтобы синхронизировать данные, я smply называют метод синхронизации Application \ Синхронизация \ SynchronizeData, в которым будет принимать конкретную реализацию SynchronizationDataSourceInterface, вызывать его методы и проверки возвращенные объекты SynchronizationDataSourceResponse перед их переносом в Domain \ Model \ Synchronization \ RunSynchronizationService?

Или следует удалить службу RunSynchronizationService (службу домена) и позволить службе приложений (SynchronizeData.php) создавать/обновлять объекты домена на каждом этапе процесса синхронизации?

+0

Возможно, я ошибаюсь, но я чувствую запах здесь. Моя первая рекомендация - изолировать синхронизацию внутри одного (суб) пакета. Моя вторая рекомендация - почему бы вам не начать с небольшого сервиса и позволить ему развиваться позже, когда вы лучше понимаете его роль. –

+0

@IhorBurlachenko проблема в том, что процесс синхронизации относительно огромен. Я должен получать и проверять от 5 до 10 ответов от API для каждого объекта, и их, по меньшей мере, 700 из них – Lucio

+0

. Затем я бы спрятал все детали в пакете Synchronization (sub-). Я бы ничего не добавил в слой домена. Если я правильно понял, что синхронизация не связана с доменом, это просто способ работы вашего приложения с данными. –

ответ

2

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

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

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

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

Если валидация требует от вас сравнить данные домена, она, вероятно, должна находиться в модуле RunSynchronizationService.php. Этот модуль, как представляется, несет ответственность за получение данных синхронизации и их применение в вашем домене.

Если валидация выполняется на основе данных, возвращаемых из вызова службы синхронизации, и не требует прямого доступа к графу объектов домена, я бы поставил эту проверку на реализацию сервиса интерфейса и выставлял этот запрос проверки сервисный интерфейс. Чтобы справиться с ситуацией, когда эта проверка была одинаковой для нескольких версий службы синхронизации (таких как VersionA, VersionB и т. Д.), Вы можете использовать наследование и переопределения или общие вспомогательные функции для службы синхронизации и т. Д. В моем примере ниже, Я использовал наследование.

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

Уровень приложения должен отвечать за создание экземпляра службы (MySpecificRemoteApiDataSource) и передать его в модуль RunSynchronizationService.php как SynchronizationDataSourceInterface. Если существует несколько версий, прикладной уровень, вероятно, будет отвечать за выбор того, какой из них (из конфигурации, возможно), и с использованием фабрики.

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

Domain - 
    Model - // my set of entities and repository interfaces are here 
     .... 
    Synchronization - 
     RunSynchronizationService.php // domain service 
     SynchronizationDataSourceInterface.php // used to define the contract associated with a sync service 
     SynchronizationDataSourceResponse.php // this would be returned by each call of SynchronizationDataSourceInterface method, and would contain data normalized, but not validated. 
Application - 
    Synchronization - 
     SynchronizeData.php // application service - Uses a factory or some means of determining which version to use and introduce the domain to the data point. 

Infrastructure - 
    MyConcreteImplementationOfModelEntityRepository.php 

Synchornization - 
    VersionA - 
     MySpecificRemoteApiDataSource.php // Implements SynchronizationDataSourceInterface.php, inherits from SyncApiDataSourceBase.php 
    SyncApiDataSourceBase.php // Common logic for sync goes here, such as validation. 
+0

Я почти сделал то же самое! Кроме того, я поставил конкретную реализацию «SynchronizationDatasourceInterface» в «Инфраструктура/Синхронизация». Тем не менее, это отличный ответ, спасибо! – Lucio