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

DataMapper, Identity Map, связанные объекты, как правильно построить архитектуру?

Добрый день.
Реализую шаблон DataMapper. Возник вопрос. Для создания объекта на основании данных из БД (массив, содержащий данные о строке) в каждом объекте Mapper используется функция createObject. Что-то вроде:
protected function doCreateObject(array $data) {
			$obj = new File();
			$obj->setTitle($data['title']);
			$obj->setPath($data['path']);
			$obj->setType($data['type']);
			$obj->setSize($data['size']);
			$obj->setId($data['id']);
			return $obj;
		}

Когда сущность более сложная, к примеру User, у которого также есть аватар, метод выглядит следующим образом:
protected function doCreateObject(array $data) {
			$obj = new User();
			$obj->setFirstName($data['firstname']);
			$obj->setLastName($data['lastname']);
			$obj->setEmail($data['email']);
			$obj->setId($data['id']);

			$fileMapper = new FileMapper();
			if($data['id_avatar']) {
				$fileData = array("id"    => $data['id_avatar'],
								  "path"  => $data['path'],
								  "size"  => $data['size'],
								  "title" => $data["title"],
								  "type"  => $data["type"]);

				$avatar = $fileMapper->createObject($fileData);
			} else {
				$avatar = null;
			}

			$obj->setAvatar($avatar);

			return $obj;
		}

1) Тут же вопрос, правильно ли то, что UserMapper точно знает какие нужны поля для передачи их в FileMapper. Т.е. верный ли это способ создания объектов в данном случае.

2) Когда я у сущности User вызываю метод getEvents, создается коллекция объектов типа Event.
Объект Event должен в себе содержать ссылку на автора(User). Таким образом, когда мне нужно получить все события(Events), я делаю запрос вроде
SELECT * FROM events WHERE id_author=?
т.е. не объединяю Events и Users, что логично, т.к. у меня уже есть нужный мне объект User(именно у него я вызывал getEvents)
А вот с методом createObject объекта Event теперь проблема. Вот примерный код метода:
protected function doCreateObject(array $data) {
            $obj = new Event();
            $obj->setId($data['id']);
            $obj->setTitle($data['title']);
            $obj->setDescription($data['description']);
            $obj->setCreateDate($data['create_date']);
            $obj->setTimeStart($data['time_start']);
            $obj->setTimeFinish($data['time_finish']);

            $userMapper = new UserMapper();

            $creator = $userMapper->createObject(array($data['id_author']));
          
            $obj->setCreator($creator);

            return $obj;
        }

т.к. я использую шаблон Identity Map, createObject для UserMapper вернет мне мой существующий объект User.
Но есть другая ситуация, когда к примеру я получаю все Events - тогда мне необходим запрос вроде
Select * from events join users on events.id_author=users.id

И теперь вызов createObject для userMapper должен быть вроде
$userMapper->createObject(array($data['id_author'], $data['firstname'], $data['lastname']));


Как правильно разграничить эти 2 условия в EventsMapper->createObject или нужно реализовать это вообще по другому?

Благодарю
  • Вопрос задан
  • 2994 просмотра
Подписаться 2 Оценить Комментировать
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Мне кажется вам стоит пересмотреть то, как вы создаете объекты. В частности вам нужно хранить какие-то методанные как что собирать и не делать мэппер для каждого объекта а просто что бы на основе метаданных генерились оные одним мэппером который просто умеет разруливать связи.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
IT ATLAS Москва
от 250 000 до 500 000 ₽