Добавление статуса ожидания и активности пользователя. Реализация команды подтверждения регистрации по токену из ссылки в электронном письме.
- 00:00:37 Тест неподтверждённой регистрации
- 00:01:17 Скалярное значение статуса
- 00:02:11 Класс-словарь статусов
- 00:02:49 Объект-значение
- 00:03:46 Разделение ответственностей
- 00:04:54 Реализация класса для статусов
- 00:06:10 Сокрытие реализации
- 00:07:18 Юзкейс подтверждения регистрации
- 00:09:35 Тест для метода подтверждения
- 00:11:17 Построитель сущности для тестов
- 00:16:16 Метод confirmJoin
- 00:16:34 Инкапсуляция валидации токена
- 00:19:04 Проверка работы
- 00:19:45 Обзор результата
Скрытый контент (код, слайды, ...) для подписчиков.
Открыть →Чтобы не пропускать новые эпизоды подпишитесь на наш канал @deworkerpro в Telegram
Я немного не понял зачем в конструкторе по умолчанию ставить статус? А если мне потребуется из массива заполнить класс User данными? Получается, что статус будет не активный, но а пользователь на самом деле активен. Т.е. через конструктор я не смогу указать текущий статус? Поясните, пожалуйста, в чем дело.
Конструктор используется по назначению только для первого создания объекта. Как и другие методы он содержит свою бизнес-логику, по которой может присваивать первоначальные значения, бросать исключения и генерировать события.
В случае же восстановления объекта по массиву из БД конструктор не используют. Вместо этого объект там создаётся без конструктора и заполняется данными прямо в приватные поля через рефлексию.
Например, пишем гидратор или находим любой готовый вроде такого:
и с помощью него десериализуем объект текущими данными из БД:
Если же нужно просто в разных юзкейсах создавать объект по-разному, то в этом случае можно сделать несколько именованных конструкторов, как мы делали в видео о конструкторах. В будущем эпизоде про регистрацию через соцсети мы сделаем именно так.
Спасибо за ответ. Сегодня обязательно видео посмотрю.
Дмитрий, часто сталкиваюсь с понятием гидратор, но до конца не понимаю принцип его работы, есть ли у вас материал по нему, дайте ссылочку для ознакомления пожалуйста
В ответе как раз привел пример гидратора. Ещё про него рассказывал раньше здесь.
Всем привет. Дмитрий, добрый день. Вот у меня такой вопрос возник. У нас хендлеры не могут быть описаны каким-то единым интерфейсом, т.к. на вход принимают разные команды. Точнее можно сделать команды , реализующие некий интерфейс или унаследованные от какой-то абстрактной команды, но тут уже будет какой-то костыль.
И вот у меня возникла потребность задекорировать все хендлеры, добавив логирование начала и конца работы каждого хендлера. Как-то это можно реализовать без костылей?
В языках с дженериками можно указать общий интерфейс.
В PHP без шаблонов это пока не работает.
В любом языке можно сделать свой интерфейс CommandBus для запуска команд и декорировать уже шину. В PHP можно взять league/tactician и реализовать логирование через middleware в ней.
Не подскажете еще как быть с автовайрингом? Пытался внедрить симфонячий мессенджер. Указал в конфиге
Но если в хендлер внедряется MessageBusInterface, то получается Circular dependency. И вот что-то ума не приложу как эту беду победить.
Переделать Locator на доставание хендлера только по требованию:
Спасибо, Дмитрий. Пришлось переписать локатор и всё заработало.
Дмитрий, вы показали как вынести в отдельный класс операции со статусами.
Но есть ещё несколько часто используемых операций:
Как бы вы решили такую задачу в рамках DDD ?
Обычно название статуса нужно только для отображения на фронтенде. Домену интересен только код. Поэтому все эти преобразования будут только снаружи в контроллерах или в файлах переводов. Поэтому если для сериализации используется пакет вроде symfony/serializer, то для статуса легко пишется кастомный сериализатор.
Почему мы не используем mock в unit тестах? Когда вообще надо использовать мок? Нафига он нужен в принципе?
Моки и стабы будут в 17-ом эпизоде, когда с их помощью нужно будет имитировать зависимости.
if (is_null($this->joinConfirmToken))
- такого не может быть ведь мы в Сommand ищем юзера по токенуКак мы дойдем до "User has already been confirmed!" если в этом случае токен null, а мы ищем юзера по токену?
Не является ли это логической ошибкой? Дмитрий
Сейчас
confirmJoin
мы используем только в обработчике команды, поэтому проверка выглядит избыточно. Но скоро начнём его вызывать вUserBuilder
и в фикстурах для заполнения БД демо-данными для разработки и для тестов. И тогда появятся проблемы, если такой проверки у нас не будет.Поэтому любому методу должно быть всё равно, откуда и как его вызывают выше. Все проверки в нём должны быть всегда.
Так себе идея - искать юзера по токену. Нужен дополнительный индекс ради одноразовой операции Если колонка не uuid, а хранится в бд как строка, то индекс ещё и большой будет. Почему-бы вместе с токеном в команду не пихнуть id юзера? Как вариант без id - хранить токены в отдельной таблице, но тогда до запрос или join придётся делать при обычном findById, что-бы все данные стянуть для модели.
Если передавать id, то в ссылку подтверждения тоже придётся подставлять id и token.
Да, можно сохранить в другой таблице и токен привязать через связь, если есть смысл в такой экономии.
Еще можно использовать разряженный или условный индекс в pgsql/mongo, но придётся для любого токена его все-равно создавать.
забыли StatusTest показать
Или войти через: