@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 или нужно реализовать это вообще по другому?

Благодарю
  • Вопрос задан
  • 2977 просмотров
Пригласить эксперта
Ответы на вопрос 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Мне кажется вам стоит пересмотреть то, как вы создаете объекты. В частности вам нужно хранить какие-то методанные как что собирать и не делать мэппер для каждого объекта а просто что бы на основе метаданных генерились оные одним мэппером который просто умеет разруливать связи.
Ответ написан
Ваш ответ на вопрос

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

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