Задать вопрос

Как следует организовать работу с entity?

Доброго времени суток.

Есть проект на PHP c Yii2 и ~DDD. Все данные предоставляются пользователям на двух языках: Русском и Английском.

В рамках проекта есть сущность Disease (для примера), привязанная к конкретному пользователю.
class Disease 
{
	/**
	 * @var string
	 */
	public $id;

	/**
	 * @var int
	 */
	public $userId;

	/**
	 * @var string
	 */
	public $icd10Code;

	/**
	 * @var string
	 */
	public $userBasedValue;
}

(ICD-10 - классификатор заболеваний Всемирной Организации Здравоохранения)

Данная сущность не содержит название заболевания, т.к. оно будет разным на разных языках. Сейчас название (как и все остальные локализованные данные, ряд данных завязан также на пользователя, который выполняет запрос) подтягивается на этапе формирования ответа (в трасформере Fractal'а, презентационный слой). Но теперь появилась необходимость добавить новый источник данных, который требует передавать язык и данные пользователя, необходимые для формирования ответа, в качества параметра запроса и, соответственно, возвращает полностью локализованные данные по заболеванию с учетом переданных данных пользователей.
Данные из этих двух источников объединяются и выводятся в одном списке.

Как корректно решить данную задачу? Использовать instanceof в трансформере особо нет желания...

Пока в голову приходит лишь такой вариант:
Сделать сущность LocalizedDisease (потомок Disease с доп. полями $title и $userBasedValueDescription) для нового репозитория, далее обернуть получение полного списка заболеваний в некий DiseaseService::getList(), который будет дергать оба репозитория и оборачивать каждый полученный объект (Disease или LocalizedDisease) в объект соответствующего класса имплементирующего интерфейс вида:
interface DiseasePresenterInterface
{
	public getICD10Code(): string;

	public getTitle(): string;

	public getUserBasedValueDescription(): string;
}

Который уже и определяет откуда брать данные по заболеванию для конкретного пользователя. В итоге получится, что DiseasePresenter (для старого класса Disease) будет дергать спец. репозиторий с заболеваниями (который сейчас дергает трансформер Фрактала) по Disease::$id, а LocalizedDiseasePresenter (для LocalizedDisease) будет просто использовать значение переменных LocalizedDisease::$title и LocalizedDisease::$userBasedDescription.

Но что-то мне подсказывает, что это не самый правильный способ решить данную задачу...
  • Вопрос задан
  • 353 просмотра
Подписаться 2 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 2
@kn0ckn0ck
Продюсер
Я так не стал бы делать. Нужно лучше продумать проблемную область. В данном примере, некорректно использованы названия. Книга она по определению уже локализованная. Переводчики и редакторы у русскоязычной книги совсем не те, кто писал и редактировал оригинал. Здесь явно нужно выделить исходный объект авторского права (оригинальное издание) и производные - редакции и переводные издания. У каждого издания есть свое название и другие характеристики.

В данном случае, здесь не стоит вопрос локализации. Здесь стоит вопрос более корректного анализа и моделирования предметной области.

Кстати, локализацию через доп. сущности вообще как-то странно решать. Это исключительно презентационный слой.
Ответ написан
@ddd329
Сущности и агрегаты нужны для реализации бизнес-логики, чтобы ты не смог в базу данных записать недостоверную и/или противоречивую информацию, и все!
На экране ты отображаешь не сущности и агрегаты, а скорее информацию о них... Когда ты думаешь о выводе данных на экран, то не должен даже мыслить агрегатами, потому как агрегаты являются единицами изменения, а не порция для отображения.
Поэтому можешь обращаться на прямую в БД с запросом выдать тебе информацию, или создать отдельную Модель Чтения, и через ORM читать данные.

Создавать сущность LocalizedDisease не имеет смысла, так как не реализует новое поведение. Вообще сущность это в идеале только поведение, и не важно какие у него данные, то есть принцип здесь - "Говори а не спрашивай"
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы