Я пытаюсь использовать шаблон стратегии для решения проблемы дизайна. Это система колледжей. Есть Пользователь, и пользователь может быть Студентом, Профессором или Администратором. Итак, у меня есть User
сущность как это
<?php
namespace Domain\Model\User;
class User
{
private $user_type;
public function __construct(UserType $user_type)
{
$this->user_type = $user_type;
}
public function hasAccess()
{
$this->type()->hasAccess();
}
// others methods
}
UserType
Интерфейс, который реализует каждый тип пользователя. Словно StudentType
:
<?php
namespace Domain\Model\User;
class StudentType implements UserType
{
public function hasAccess()
{
// checks if has access
}
}
Обратите внимание, что я не хочу создавать ACL с Strategy Pattern
Я уже использую один. Дело в том, что у каждого типа пользователей есть свой способ доступа к среде, поэтому я должен сделать некоторые проверки.
Таким образом, вопрос заключается в методе type()
из User
юридическое лицо. Я знаю, что мне не нужно думать о базе данных при моделировании моих сущностей, но все эти типы, пользователи, студенты хранятся в реляционной базе данных, и я не могу этого избежать. Итак, я использую Doctrine
для настойчивости.
Когда я получаю User
из базы данных, Doctrine не использует конструктор моего User
, Итак $user_type
Атрибутом будет только число. Затем, чтобы гарантировать, что $user_type
Свойство всегда будет классом, который реализует UserType
интерфейс, я должен был использовать type()
способ сделать что-то вроде этого
// method inside User class
public function type()
{
if (!$this->user_type instanceof UserType) {
switch ($this->user_type) {
case 1:
$this->user_type = new StudentType;
break;
// some others ugly conditions for each type
}
}
return $this->user_type;
}
Есть ли способ избежать использования этих условий? Или я неправильно думаю о паттерне стратегии?
Вы можете подключиться к postLoad
событие в Доктрине EventManager
увидеть этот. Это событие позволит вам обрабатывать каждую сущность после ее загрузки из БД.
Лично я не люблю использовать EventManager
слишком много, и я не люблю, чтобы сущности были «слишком умными». Я думаю, что пример User
Сам объект не должен быть в состоянии решить, имеет ли он доступ где-либо или нет. Некоторые бизнес-объекты / услуги должны нести ответственность за решение этого. Эта услуга будет иметь hasAccess
метод, который принимает ваш User
сущность и ответы соответственно. (Имея логику вашего StudentType
, TeacherType
и т. д.) Тогда служба сможет справиться user_type
или роль, независимо от того, является ли это целое число или строка.
Других решений пока нет …