Если бизнес-логика хочет отправить электронное письмо - PullRequest
3 голосов
/ 21 июня 2019

Я пытаюсь реализовать Чистую Архитектуру Дяди Боба:

Uncle Bob's Clean Architecture

Все в порядке, кроме UseCases / Interactors.Мне нужно зарегистрировать пользователя, поэтому мне нужно RegisterUser UseCase.В конкретном интеракторе я реализую сценарий использования RegisterUser, который просто создает объект User и хэширует его пароль с портом PasswordBroker.

После создания пользователя мне нужно отправить подтверждениеЭл. адрес.Для этого мне нужно использовать компонент фреймворка.И есть две основные проблемы:

  1. Я думаю, что нет смысла писать порт для почтовой службы, потому что этот порт будет просто огромной абстракцией копирования / вставкиFramework Framework
  2. Interactor не может отправить электронное письмо после создания пользователя, поскольку пользователь, наконец, будет сохранен после Doctrine flush() внутри контроллера.Существует риск, когда мы отправили электронное письмо, но Пользователь не был сохранен в БД.Он должен быть согласованным.

Какой лучший подход в этом случае?

Я думаю, нам нужен какой-то порт , который относится к конкретному варианту использования,этот порт будет вызываться в конце сценария использования и реализован в Application Layer , где доступны фреймворк Mailer и Doctrine.

Ответы [ 2 ]

2 голосов
/ 25 июня 2019
  1. Я думаю, что нет смысла писать порт для почтовой службы, потому что этот порт будет просто огромной абстракцией копирования / вставки фреймворковой службы

Я бы создал Notification интерфейс, который я передаю интерактивному сценарию использования, аналогично EntityGateway или EntityRepository.

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

В таком случае Notification может выглядеть следующим образом:

public interface Notification {
    public void notifyUserRegistered(User user);
}

Реализация будет размещена на внешнем уровне, обычноуровень адаптеров интерфейса.Потому что это уровень, где интерфейсы внутренних уровней адаптируются - поэтому название.

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

Interactor не может отправить электронное письмо после создания пользователя, поскольку пользователь, наконец, будет сохранен после Doctrine flush () внутри контроллера.Существует риск, когда мы отправили электронное письмо, но Пользователь не был сохранен в БД.Оно должно быть согласованным.

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

Но вы обычно можете зарегистрироваться в активной транзакции, чтобы получать информацию об ее успешном завершении.Это означает, что реализация Notification просто зарегистрирует обратный вызов, который вызывается после завершения транзакции.Затем вы можете отправить электронное письмо.

Я не знаю, как это можно сделать в php, возможно, это еще один вопрос здесь, на SO.В Java есть несколько способов, в зависимости от используемого API транзакции.

Для Spring взгляните на Связанные с транзакцией события или JEE's TransactionSynchronizationRegistry .Просто упомянуть некоторых, если разработчики Java читают это.

1 голос
/ 21 июня 2019

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...