Как службы должны общаться друг с другом?

Во время обучения у @ tereško’s ответ о том, как должна быть структурирована модель, я не могу найти лучший способ связи между службами. Я также нашел этот Ответ, который похож на ситуацию, с которой я имею дело, но пример отлично подходит для демонстрации. Итак, в этом смысле, как я могу получить службу распознавания внутри службы блога, например, когда служба имеет доступ только к объектам фабрики домена и маппера. Я посылаю это от контроллера? Или мне тоже нужно отправить сервисную фабрику?

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

class BlogService
{
public function storePost($title, $content)
{
$post   = $this->domainFactory->build('Post');
$mapper = $this->mapperFactory->build('Post');

$post->setTitle($title);
$post->setContent($content);
$post->setAuthor( /* get logged in user */ );

$mapper->save($post);
}
}

2

Решение

Теория

Так что в основном ваш вопрос «Как поделиться объектом домена из службы распознавания с какой-либо службой контента?». Я действительно думал об этом в течение некоторого времени.

На мой взгляд, здесь есть 4 варианта. Два дерьмовых, один хороший и один промежуточный:

  1. Ранее упоминался подход «Пройди сервисную фабрику».

    Это наиболее наивное решение, потому что в реальной ситуации вы получите неконтролируемый рост графа объектов — сервис, содержащий сервисы, содержащие сервисы. до тошноты.

    Это неустойчиво, но быстро.

  2. Измените службу распознавания таким образом, чтобы она Account экземпляр в контроллер, который затем, в свою очередь, передает другим службам.

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

    Это хак и плохая архитектура.

  3. Используйте DI-контейнер для совместного использования объектов домена (и даже сопоставителей) между службами.

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

    Лучший вариант, но требует дополнительных навыков и кода.

  4. Используйте фабрику объектов вашего домена для создания экземпляра Account (и все остальные или выбранные) только один раз.

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

    Это сложное промежуточное решение, но оно позволяет вам хранить знакомый API в сервисах.

исповедь

Я сам в настоящее время использую вариант 2. Причина в том, что у меня нет контейнера DI, который я мог бы использовать (и я подумал о «варианте 4» только 5 минут назад). Большинство из того, что вы видите под описанием «Контейнер PHP DI», на самом деле представляют собой различные сервисные локаторы (в любом случае вам лучше работать с кучей фабрик).

Если вы хотите пойти с DI-контейнером, моя поддержка идет в Auryn.

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

Постскриптум

Вместо того чтобы писать это:

 $post->setAuthor($user);

Вы должны написать что-то вроде этого:

$post->setAuthorId($user->getId());

.. по двум причинам:

  • Вы не используете активную запись. Поэтому вам не нужно Post Например, чтобы управлять своими отношениями с другими лицами. Вот для чего у вас есть сервис.
  • Если вы прошли весь Account Например, вы бы в конечном итоге извлечь идентификатор в любом случае. Так что вы будете нарушать Закон Деметры никакой практической пользы.
11

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

Я предполагаю, что domainFactory и mapperFactory являются экземплярами шаблона Abstract Factory.

Поскольку ваш BlogService уже требует этих двух абстрактных фабрик, почему бы не иметь третью, ServiceFactory.

Ответственность за этот объект будет заключаться в создании (предпочтительно абстрактных) продуктов, услуг.

http://en.wikipedia.org/wiki/Abstract_factory_pattern

1

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