ну да, это же дополнительный запрос или джойнТы говоришь, что тебе не нравится $server->getCustomer()->getId(). Ты не уточнил почему, но, возможно, в силу избыточности/неэффективности.
бизнес-логику я выношу в сервисы, а в саму сущность которая для персистенции стараюсь не перегружать бизнес-логикойА где тогда находится твоя бизнес-логика?
/**
* @param Customer $customer
* @return Server
*/
public function setCustomer($customer)
{
$this->customer = $customer;
$this->customerId = $customer ? $customer->getId() : NULL;
return $this;
}
а если сделал неправильно чтоб фигачило электрошоком, иначе все равно будутUPD: в целом жду того, что инструмент будет устроен так, что сделать правильно - проще и быстрее, чем неправильно
Я не зря спросил про то, что ты ждёшь от инструмента, потому что слабо себе представляю что именно тут вписывается в роль «инструмента».Ну, смотри
1) инструмент и документация к нему навязывают стиль мышления. Использовать DDD+CQRS-подход намного проще, если инструмент помогает, а не мешает.
2) поменьше бойлерплейта и стандартные документированные конструкции - программист существо ленивое и предпочитает идти по проторенной дорожке.
UPD: в целом жду того, что инструмент будет устроен так, что сделать правильно - проще и быстрее, чем неправильно
Иными словами — для отображения в отдельно взятых случаях. ServerExtendedReadModel {"id": 42, "customer": { ... }, ...} (грязноватое имя, но суть в том, что моделей на чтение может несколько).$customer мне в общем то нужен в виде объекта в классе Server - всякие там гриды и тп,
«Персистентная» — это та, которую сохраняют. Read models никуда не сохраняют по определению: они нужны только для чтения.насчет разных персистентных сущностей для разных контекстов мысль интересная
С остальным хорошие примеры есть и так.маппинг сущности из БД, маппинг сущности на БД, получение read model из БД
Это решается документацией и туториалами.При этом, ни один инструмент не заставит разработчика писать грамотные бизнес-события в стиле ServerWasTransferred вместо CRUD-like ServerWasUpdated. Это нужно просто понять.
public function findById(int $fooId): Foo
{
$doctrineEntity = $this->fooDoctrineRepository->find($id);
return $this->hydrator->hydrate($doctrineEntity->toArray(), new Foo());
}
public function save(Foo $foo)
{
$doctrineEntity = $this->entityManager->getReference(Foo::class, $id);
foreach ($foo->events() as $event) {
$this->{eventToMethodName($event)}($doctrineEntity, $event);
}
$this->fooDoctrineRepository->save($doctrineEntity);
}
private function onFooWasRenamed(FooDoctrineEntity $foo, FooWasRenamed $event) {
$foo->setName($event->getNewName());
}
Кстати. Я в последнем проекте вообще в итоге забил на объекты и тупо массивы возвращал, т.к. получалось очень дофига вариаций. Либо кучу почти одинаковых объектов плодить пришлось бы, либо в один всё свойства добавить и полупустым таскать, или всегда с полной инфой...Иными словами — для отображения в отдельно взятых случаях. ServerExtendedReadModel {"id": 42, "customer": { ... }, ...} (грязноватое имя, но суть в том, что моделей на чтение может несколько).
Если они тупо сериализуются в API, то в итоге те же массивы и получаются. Можно вытащить наружу API наподобие того, как это сделано в GraphQL: клиент сам запрашивает список полей, а не ты пилишь отдельную read model под каждый отдельно взятый запрос.Много мест, где одни и те же "сущности" нужно отображать, но с разными наборами данных. Получалось ClientReadModel, ClientWithServicesReadModel, ClientWithLastContactReadModel и т.д., а когда понадобились всякие ClientWithServicesAndWithLastContactReadModel забил и стал массивами пользоваться, в ClientExtendedReadModel всё-всё сразу напихать тоже не вариант (сначала так и делал, были basic, extended и detailed), данных разных много - куча запросов и джойнов вхолостую гонять там где они не нужны.
Судя по задаче, тебе надо просто взять поля и отдать в шаблон или вообще наружу через json, тут уж какая разница-то?Массивы всё-таки не так удобны...
В шаблон. Так-то да, получаемый DTO - тот же ассоциативный массив. В принципе всё верно, но у объекта автокомплит, плюс можно простенький сахарок подкрутить, вроде $client->isSomeStatus() вместо $client['status'] === ClientStaus::SOME_STATUSСудя по задаче, тебе надо просто взять поля и отдать в шаблон или вообще наружу через json, тут уж какая разница-то?