Конструкторы и зависимости

Использование конструкторов для инициализации объектов. Внедрение зависимостей. Разница конструкторов сущностей и сервисов.

  • 00:00:20 - Geometry
  • 00:01:00 - Point
  • 00:06:10 - Circle
  • 00:10:34 - User
  • 00:17:17 - Email
  • 00:18:33 - Phone
  • 00:21:00 - PHP
  • 00:22:48 - Именованные конструкторы
  • 00:26:30 - Сущности и сервисы
  • 00:27:17 - PasswordHasher
  • 00:28:52 - Handler
  • 00:30:54 - ConfirmTokenSender
  • 00:35:32 - Подведение итогов
Скрытый контент
Комментарии (14)
Сергей

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

Ответить
Сулейман

+

Ответить
Артем

+

Ответить
Владимир Перепеченко

+

Ответить
S.Polessky

+

Ответить
Владимир Перепеченко

Моей ошибкой было начинать смотреть касты про аукцион, не ознакомившись с подходами, освещенными в серии "Взаимодействие объектов". Благодарю.

Ответить
Владимир Перепеченко

Кстати, будет здорово, если поделитесь мыслями о желательном порядке изучения Ваших материалов. А уже каждый подумает, какой у него уровень и с какого каста/курса начать.

Ответить
S.Polessky

Советую интенсив по ООП посмотреть - значительно поможет освоится.

Ответить
Сидредин

А где этот интенсив?

Ответить
S.Polessky

Вопрос по разделению ответственности Сервисов

Есть сервис регистрации SignupService, который выполняет регистрацию пользователя.

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

public function signupByGuestOrder(OrderGuestForm $guestForm, $ip, $partnerId)
{
    $username = $this->usernameUniqueService->process((explode("@", $guestForm->email))[0]);
    $user = User::requestSignupByOrder($username, $guestForm->email, $ip, $partnerId);
    $this->users->add($user);
}

Вопрос: Нам следует эту логику поместить в отдельный SignupByOrderService или можно оставить в SignupService? Где та самая грань, когда надо создавать новый сервис?

P.S. В данном случае оставил в SignupService.

Ответить
Дмитрий Елисеев

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

Ответить
S.Polessky

Можно ли в сущности использовать сервисы?

В методе signupByGuestOrder с помощью UsernameUniqueService мы проверяем уникальность имени/генерируем уникальное:

public function signupByGuestOrder(OrderGuestForm $guestForm, $ip, $partnerId)
{
    $username = $this->usernameUniqueService->process((explode("@", $guestForm->email))[0]);
    $user = User::requestSignupByOrder($username, $guestForm->email, $ip, $partnerId);
    $this->users->add($user);
}

Но нам было бы удобнее генерировать username в именованном конструкторе User::requestSignupByOrder, как мы это делаем с паролем:

public static function requestSignupByOrder($username, $email, $ip, $partnerId)
{
    $password = Yii::$app->security->generateRandomString(8);
    $user = self::requestSignup($username, $email, $password, $ip, $partnerId);
    $user->recordEvent(new SignupByOrderEvent($user, $password));

    return $user;
}

Можно ли в сущности использовать сервисы?

Ответить
Дмитрий Елисеев

Можно, если сервис передавать в сам метод:

public static function requestSignupByOrder($username, $email, Security $security)
{
    $password = $security->generateRandomString(8);
    $user = self::requestSignup($username, $email, $password);
    $user->recordEvent(new SignupByOrderEvent($user, $password));

    return $user;
}

Об этом опубликовал статью о внедрении зависимостей в своём блоге.

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

public static function requestSignupByOrder($username, $email, PasswordGenerator $generator)
{
    $password = $generator->generate();
    $user = self::requestSignup($username, $email, $passwordd);
    $user->recordEvent(new SignupByOrderEvent($user, $password));

    return $user;
}

Это будет удобно и в юнит-тестах, когда там будем делать стаб или мок для этого генератора.

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий

Или войти через:

Google
GitHub
Yandex
MailRu