dm84ya08
@dm84ya08
Самоучка

Как получить доступ к объекту А содержащего объект Б из объекта Б?

Изучаю PHP и ООП. В качестве обучения выбрал задачу - создание простенького сервиса на подобие интернет магазина.
В процедурном стиле удалось реализовать основной функционал. Решил перевести его в ОО стиль, для закрепления прочитанного из книг. Столкнулся с проблемой перехода от ассоциативных массивов к объектам.
Имеется массив содержащий заказы пользователей и сведения об их оплате следующей структуры:

[x] – заказ
  [user] – информация о покупателе
  [pays] - платежи
    [x] – конкретная оплата и сведения о ней
  [orders] - товары заказанные покупателем
    [x] – товар и сведения о нём

При помощи массивов мне удалось получать все данные о заказе путём прямого обращения к конкретным полям массива. Например, для добавления информации о конкретном платеже в БД, мне так же необходима информация о покупателе - его ID.

Я решил переделать данную структуру в объекты. Заменил заказы на объект Lot содержащий объект User и массивы из объектов Pay и Orders. Таким образом:

foreach ($purchase as $lot) {
  $lots[] = new Lot($lot);
}

где, Lot:

class Lot {
  /**@var array Массив объектов с товарами */
  private $orders = array();
  /** @var array Массив объектов с платежами */
  private $pays = array();
  /** @var User Данные о покупателе */
  private $user;

  function __construct (array $lot) {
    $this->user = new User ($lot['user']);
    // Список платежей
    if (!empty($lot['pays'])) {
      foreach ($lot['pays'] as $pay) {
        $payObj = new Pay($pay);
        $this->pays[] = $payObj;
      }
    }
    // Список товаров
    if (!empty($lot['orders'])) {
      foreach ($lot['orders'] as $order) {
        $orderObj = new Order($order);
        $this->orders[] = $orderObj;
      }
    }
  }
}

Я понимаю, что скорее всего не правильно всё спроектировал. Поэтому прошу любой помощи.

1. Как правильно спроектировать класс который бы описывал структуру содержащуюся в представленном выше массиве?
2. Может быть есть какой-то шаблон проектирования для решения данной задачи?
3. Не могу понять как получить доступ из конкретного объекта Pay к объекту User, чтобы получить ID пользователя который внёс данный платёж?
4. Есть мысль передавать ссылку на объект Lot (self), в объект Pay при создании. Насколько это правильно?

Заранее спасибо.
  • Вопрос задан
  • 497 просмотров
Решения вопроса 1
@matperez
1. Мне кажется, нет смысла выделять платежи пользователя в отдельную сущность и хранить их в модели пользователя, ведь они не существуют без заказов. Их лучше выделить в атрибуты заказа (например: когда оплачен, каким образом, id платежной транзакции).
3. Исходя из первого пункта, доступ к пользователю можно получить через заказ. Т.е. сначала по id платежа (транзакции) получаете заказ, а уже из заказа получаете ссылку на пользователя который этот заказ сделал.

То, что вас интересует, скорее всего описывается в такой вещи как предметно ориентированное программирование habrahabr.ru/post/61524/. Так же стоит почитать про реляционные базы данных и их нормальные формы habrahabr.ru/post/129195/.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Tpona
@Tpona
Ужасный перфекционист
На мой взгляд, Вам нужно для начала определить место хранения данных.
Почитайте про MVC-паттерн проектирования приложений и выберите для изучения MVC-framework, например yiiframework.com.
Потому, что потом Вы все-равно к этому придете, но путь будет долгим ))
Ответ написан
max-kuznetsov
@max-kuznetsov
Главный IT-архитектор
Всё просто. Делаете класс для объекта А. Затем - класс для объекта Б. В классе Б объявляете поле a типа А. В классе А - поле b типа Б. Изначально при создании экземпляра класса А ссылка на объект класса Б в поле b будет пустой (null). При создании экземпляра класса Б его поле a со ссылкой на объект класса А тоже будет содержать пустое значение null. Пусть для объекта А задан метод Link, который в качестве параметра получает ссылку на объект класса Б. Внутри этого метода можно присвоить полю A.b указанную ссылку на объект Б, а затем полю Б.а можно присвоить ссылку на объект А, метод Link которого был вызван.

Объект Б можно создавать в конструкторе объекта А, тогда там же задавайте значения полям.

Аналогично, можно в классе А задать поле типа массив объектов Б. При внесении нового объекта в массив можно задавать ссылку на А в поле Б.a.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы