Как правильно сделать с точки зрения ООП и здравого смысла? Необходимо сделать активацию аккаунта пользователя.
Есть сущность user, с методом активации:User entityclass User
{
private $is_active = false;
public function activate(string $activation_token) : void
{
if ($activation_token !== $this->getActivationToken()) {
throw new UserActivationFailException();
}
$this->is_active = true;
}
public function getActivationToken() : string
{
//генерация ключа активации
}
}
И реализация активации:Экшн контроллераpublic function completeSignUpAction(Request $request) : Response
{
$email = mb_strtolower(trim($request->get('email')), 'UTF-8');
$activation_token = trim($request->get('token'));
//валидация
$entity_manager = $this->getDoctrine()->getManager();
try {
//ну или в контейнер можно положить
(new UserActivator($entity_manager))->activate($email, $activation_token);
} catch (UserActivationFailException $e) {
throw new NotFoundHttpException();
}
return new RedirectResponse($this->generateUrl('login'));
}UserActivatorclass UserActivator
{
private $entity_manager;
public function __construct(EntityManager $entity_manager)
{
$this->entity_manager = $entity_manager;
}
public function activate(string $email, string $activation_token) : void
{
//проверка входных данных
$user_repository = $this->entity_manager->getRepository(User::class);
$user = $user_repository->findOneBy(['email' => $email]);
if (is_null($user)) {
throw new UserActivationFailException();
}
$user->activate($activation_token);
$this->entity_manager->flush($user);
}
}
По логике ответственность за активацию конкретного аккаунта несет сущность User т.к. ей хватает данных для этого.
Но если я правильно понял, то сущность не должна иметь доступ к своему репозиторию. И чтобы сохранить в бд изменения необходимо завернуть активацию в сервис и передать в него зависимости неоходимые для сохранения в бд. Или я не правильно понял?
Правильно ли делать такие сервисы как UserActivator и не будет ли большого разрастания подобных классов, если после изменения состояния сущность нужно будет сохранить изменения в бд?
Вобщем как правильно сделать?

21 Авг 2019 в 07:02
194 +1
1
Ответы
1

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

Следует разделить ответственности: сущность пользователя (User) должна знать только о своих собственных данный и логике активации, но не должна иметь прямого доступа к репозиторию или EntityManager.

Для сохранения изменений в БД после активации аккаунта можно использовать слой сервисов, как вы сделали в классе UserActivator. Этот подход позволяет разделить логику бизнес-операций (активация) и операции с данными (сохранение в БД).

Чтобы избежать "разрастания" подобных сервисов, можно объединить операции активации и сохранения в один сервис, например UserService. В этом случае, UserService будет содержать методы для активации аккаунта и сохранения изменений в БД, обеспечивая тем самым более компактную структуру классов.

Пример UserService:class UserService
{
private $entity_manager;

public function __construct(EntityManager $entity_manager)
{
$this->entity_manager = $entity_manager;
}
public function activateUser(string $email, string $activation_token) : void
{
$user_repository = $this->entity_manager->getRepository(User::class);
$user = $user_repository->findOneBy(['email' => $email]);
if (is_null($user)) {
throw new UserActivationFailException();
}
$user->activate($activation_token);
$this->entity_manager->flush($user);
}

}

Таким образом, использование сервиса для активации аккаунта пользователя является правильным и позволяет соблюсти принципы ООП, разделения ответственностей и повторного использования кода.

20 Апр 2024 в 13:09
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир