Использование в Entity Repository или Domain service

Обсуждаем, как правильно строить приложения
Ответить
paurlift
Сообщения: 26
Зарегистрирован: 2017.01.29, 20:16

Использование в Entity Repository или Domain service

Сообщение 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?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Использование в Entity Repository или Domain service

Сообщение 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;
		}
	}
}
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: Использование в Entity Repository или Domain service

Сообщение 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 больше вреда, чем пользы, но это по-моему), тогда проксирование. Если сущности знают про базу и могут к ней подключаться и делать запросы - тогда нужно инжектить репозиторий, либо обращаться напрямки к связанным таблицам.
glagola
Сообщения: 47
Зарегистрирован: 2017.02.22, 19:43

Re: Использование в Entity Repository или Domain service

Сообщение glagola »

anton_z писал(а): 2017.06.09, 02:01 Лично я считаю, что это абсолютно правильно - инжектить разные объекты через конструктор в сущность, хотя многие с этим не согласятся.
Тогда тот кто создает ваши сущности начинает, либо зависеть от инфраструктуры (от используемого DI контейнера), либо выступает в роли Proxy класса, импортируя зависимости необходимые для создания сущности. По мне так легче использовать доменные сервисы (они будут импортировать нужные зависимости через конструкторы), чтобы вынести логику связывающую сущность и "внешний мир".
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: Использование в Entity Repository или Domain service

Сообщение anton_z »

Если вы большую часть логики вынесете из сущностей, то у вас будет не ООП, а процедурное программирование. Ваши сущности будут анемичными контейнерами для данных. Сервисы это по сути своей процедуры, обернутые в класс. Подумайте над самим эти словом "сервис". Близко к слову "процедура", "функция". Оне не представляет объект реального мира, ничего не моделирует. Он просто инкапсулирует поведение. А кто у нас еще инкапсулирует поведение? Правильно, процедуры. Сервисы, как и процедуры, инкапсулируют поведение, не имеют своего состояния и оперируют структурами данных (чаще всего это анемичные сущности, которые уже не являются сущностями).. С ними надо осторожно и их надо стараться применять по-минимуму. Иначе получите большой набор процедур в виде классов.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Использование в Entity Repository или Domain service

Сообщение ElisDN »

anton_z писал(а): 2017.06.12, 12:16 Если вы большую часть логики вынесете из сущностей, то у вас будет не ООП, а процедурное программирование.
Большую часть выносить незачем, чтобы осталось ООП с разделением на ответственности. Просто иньектите сервисы через метод, а не через конструктор.
anton_z писал(а): 2017.06.12, 12:16 Ваши сущности будут анемичными контейнерами для данных.
Сущности оставляем объектами, инкапсулирующими поведение по работе со своими данными. В сервисы имеет смысл выносить логику по оперированию несколькими сущностями.
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: Использование в Entity Repository или Domain service

Сообщение anton_z »

ElisDN писал(а): 2017.06.13, 13:22 Сущности оставляем объектами, инкапсулирующими поведение по работе со своими данными. В сервисы имеет смысл выносить логику по оперированию несколькими сущностями.
Замечу только, что сервисы это не объекты, а процедуры, только под другим соусом. Для логики с несколькими сущностями придуманы агрегаты, разве нет?

А что так внедрения через конструктор избегаем?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Использование в Entity Repository или Domain service

Сообщение ElisDN »

anton_z писал(а): 2017.06.14, 03:02 Для логики с несколькими сущностями придуманы агрегаты
А для работы с несколькими агрегатами - доменные сервисы или прикладные юзкейсы..
anton_z писал(а): 2017.06.14, 03:02 А что так внедрения через конструктор избегаем?
Избегаем засорения конструкторов сущности десятком иньекций. Сервисы так используем только по месту, а не помещаем навсегда в приватные поля.
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: Использование в Entity Repository или Domain service

Сообщение anton_z »

ElisDN писал(а): 2017.06.14, 09:02 Для логики с несколькими сущностями придуманы агрегаты
Так агрегат это вроде понятие контекстное. Кто выполняет операцию - тот и агрегат.
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: Использование в Entity Repository или Domain service

Сообщение anton_z »

ElisDN писал(а): 2017.06.14, 09:02 Избегаем засорения конструкторов сущности десятком иньекций. Сервисы так используем только по месту, а не помещаем навсегда в приватные поля.
Это называется сверхвнедрение конструктора. Это индикатор того, что объект теряет связность. Если получается десяток внедрений - значит объект слишком за многое отвечает, надо снимать с него какую-то обязанность, делать другой класс, содержащий этот объект и нужную логику и зависимости.
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: Использование в Entity Repository или Domain service

Сообщение anton_z »

paurlift писал(а): 2017.06.08, 10:59

Код: Выделить всё


class Client implements StatefulInterface

А что за Stateful интерфейс? Вы делите объекты на stateless и stateful?! Ничего не напоминает? Функции и структуры данных, нет?
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Использование в Entity Repository или Domain service

Сообщение slavcodev »

anton_z писал(а): 2017.06.14, 14:09 А что за Stateful интерфейс? Вы делите объекты на stateless и stateful?! Ничего не напоминает? Функции и структуры данных, нет?

Код: Выделить всё

interface StatefulInterface
{
	public function changeState(State $newState);
}
Это реализация чего-то связанного со State Machine.
Жду Yii 3!
Ответить