Страница 1 из 1
Использование в Entity Repository или Domain service
Добавлено: 2017.06.08, 10:59
paurlift
Всем привет.
Код: Выделить всё
class Client implements StatefulInterface
{
private $secirutyIndetifier;
private $securityRepository
private $stateTransitionManager;
private $state;
private function __construct(
SecurityRepositoryInterface $securityRepository,
StateTransitionManagerInterface $stateTransitionManager
) {
$this->securityRepository = $securityRepository;
$this->stateTransitionManager = $stateTransitionManager;
}
public function getSecurity()
{
return $this->securityRepository->getById($this->secirutyIndetifier);
}
public function changeState(State $newState)
{
if ($this->stateTransitionManager->can($this, $this->state, $newState)) {
$this->state = $newState;
}
}
}
Цели:
1) Догружать мало используемые в entity данные только при необходимости
2) Не дать возможность сменить состояние без проверки возможности данной операции.
Состояние прикрутил к клиенту, только для примера.
Есть несколько вопросов:
1) На сколько правильно использовать внутри Entity, структуры domain слоя. (Интерфейс репозитория и сервиса проверки возможности смены состояния находятся на доменном уровне)
2) Можно ли вызывать доменные сервисы из сущности?
3) Верно ли таким образом использовать lazy loading?
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.08, 16:46
ElisDN
Код: Выделить всё
class Client implements StatefulInterface
{
private $secirutyIndetifier;
private $state;
public function changeState(State $newState, StateTransitionManagerInterface $manager)
{
if ($manager->can($this, $this->state, $newState)) {
$this->state = $newState;
}
}
}
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.09, 02:01
anton_z
paurlift писал(а): ↑2017.06.08, 10:59
1) На сколько правильно использовать внутри Entity, структуры domain слоя. (Интерфейс репозитория и сервиса проверки возможности смены состояния находятся на доменном уровне)
Лично я считаю, что это абсолютно правильно - инжектить разные объекты через конструктор в сущность, хотя многие с этим не согласятся. Сущность это тот же объект, ограничивать каким-либо образом конструирование считаю неверным.
paurlift писал(а): ↑2017.06.08, 10:59
2) Можно ли вызывать доменные сервисы из сущности?
Я думаю, можно. Сущности это не структуры данных, а объекты с поведением. Какое поведение включать в объект определяется бизнес-требованиями и программистом.
paurlift писал(а): ↑2017.06.08, 10:59
3) Верно ли таким образом использовать lazy loading?
Если у вас persitence-free сущности (по-моему от persistence-free больше вреда, чем пользы, но это по-моему), тогда проксирование. Если сущности знают про базу и могут к ней подключаться и делать запросы - тогда нужно инжектить репозиторий, либо обращаться напрямки к связанным таблицам.
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.11, 14:52
glagola
anton_z писал(а): ↑2017.06.09, 02:01
Лично я считаю, что это абсолютно правильно - инжектить разные объекты через конструктор в сущность, хотя многие с этим не согласятся.
Тогда тот кто создает ваши сущности начинает, либо зависеть от инфраструктуры (от используемого DI контейнера), либо выступает в роли Proxy класса, импортируя зависимости необходимые для создания сущности. По мне так легче использовать доменные сервисы (они будут импортировать нужные зависимости через конструкторы), чтобы вынести логику связывающую сущность и "внешний мир".
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.12, 12:16
anton_z
Если вы большую часть логики вынесете из сущностей, то у вас будет не ООП, а процедурное программирование. Ваши сущности будут анемичными контейнерами для данных. Сервисы это по сути своей процедуры, обернутые в класс. Подумайте над самим эти словом "сервис". Близко к слову "процедура", "функция". Оне не представляет объект реального мира, ничего не моделирует. Он просто инкапсулирует поведение. А кто у нас еще инкапсулирует поведение? Правильно, процедуры. Сервисы, как и процедуры, инкапсулируют поведение, не имеют своего состояния и оперируют структурами данных (чаще всего это анемичные сущности, которые уже не являются сущностями).. С ними надо осторожно и их надо стараться применять по-минимуму. Иначе получите большой набор процедур в виде классов.
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.13, 13:22
ElisDN
anton_z писал(а): ↑2017.06.12, 12:16
Если вы большую часть логики вынесете из сущностей, то у вас будет не ООП, а процедурное программирование.
Большую часть выносить незачем, чтобы осталось ООП с разделением на ответственности. Просто иньектите сервисы через метод, а не через конструктор.
anton_z писал(а): ↑2017.06.12, 12:16
Ваши сущности будут анемичными контейнерами для данных.
Сущности оставляем объектами, инкапсулирующими поведение по работе со своими данными. В сервисы имеет смысл выносить логику по оперированию несколькими сущностями.
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.14, 03:02
anton_z
ElisDN писал(а): ↑2017.06.13, 13:22
Сущности оставляем объектами, инкапсулирующими поведение по работе со своими данными. В сервисы имеет смысл выносить логику по оперированию несколькими сущностями.
Замечу только, что сервисы это не объекты, а процедуры, только под другим соусом. Для логики с несколькими сущностями придуманы агрегаты, разве нет?
А что так внедрения через конструктор избегаем?
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.14, 09:02
ElisDN
anton_z писал(а): ↑2017.06.14, 03:02
Для логики с несколькими сущностями придуманы агрегаты
А для работы с несколькими агрегатами - доменные сервисы или прикладные юзкейсы..
anton_z писал(а): ↑2017.06.14, 03:02
А что так внедрения через конструктор избегаем?
Избегаем засорения конструкторов сущности десятком иньекций. Сервисы так используем только по месту, а не помещаем навсегда в приватные поля.
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.14, 09:43
anton_z
ElisDN писал(а): ↑2017.06.14, 09:02
Для логики с несколькими сущностями придуманы агрегаты
Так агрегат это вроде понятие контекстное. Кто выполняет операцию - тот и агрегат.
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.14, 09:44
anton_z
ElisDN писал(а): ↑2017.06.14, 09:02
Избегаем засорения конструкторов сущности десятком иньекций. Сервисы так используем только по месту, а не помещаем навсегда в приватные поля.
Это называется сверхвнедрение конструктора. Это индикатор того, что объект теряет связность. Если получается десяток внедрений - значит объект слишком за многое отвечает, надо снимать с него какую-то обязанность, делать другой класс, содержащий этот объект и нужную логику и зависимости.
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.14, 14:09
anton_z
А что за Stateful интерфейс? Вы делите объекты на stateless и stateful?! Ничего не напоминает? Функции и структуры данных, нет?
Re: Использование в Entity Repository или Domain service
Добавлено: 2017.06.17, 00:47
slavcodev
anton_z писал(а): ↑2017.06.14, 14:09
А что за Stateful интерфейс? Вы делите объекты на stateless и stateful?! Ничего не напоминает? Функции и структуры данных, нет?
Код: Выделить всё
interface StatefulInterface
{
public function changeState(State $newState);
}
Это реализация чего-то связанного со State Machine.