Как мне получить доступ к переменным класса родительского объекта в PHP? - PullRequest
2 голосов
/ 15 сентября 2008

Экземпляр класса A создает пару других объектов, например, из класса B:

$foo = new B();

Я хотел бы получить доступ к переменным открытого класса A из методов в B.

Если я что-то не упустил, единственный способ сделать это - передать текущий объект экземплярам B:

$foo = new B($this);

Это лучшая практика или есть другой способ сделать это?

Ответы [ 4 ]

2 голосов
/ 15 сентября 2008

Это выглядит хорошо для меня, я склонен использовать эмпирическое правило "кто-то, поддерживающий это, понимает это?" и это легко понимаемое решение.

Если есть только одна буква "A", вы можете использовать шаблон реестра, см., Например, http://www.phppatterns.com/docs/design/the_registry

1 голос
/ 15 сентября 2008

Я бы сначала проверил, не используете ли вы неправильный шаблон: из логики вашего приложения должен ли B действительно знать об A? Если B нужно знать об A, отношения между родителями и детьми кажутся не совсем адекватными. Например, A может быть дочерним, или часть логики A может перейти в третий объект, который находится «ниже» B в иерархии (то есть не знает о B).

Тем не менее, я хотел бы предложить вам метод в B для регистрации A в качестве источника данных или создать метод в A для регистрации B в качестве Observer и метод сопоставления в B, который использует A уведомить B об изменении значения.

0 голосов
/ 19 мая 2009
$foo = new B($this);

Код такой, к сожалению, не соответствует моим потребностям. Есть ли другой способ доступа к свойствам родительского объекта?

Я постараюсь объяснить, почему. Мы пишем игровое программное обеспечение, и некоторые классы имеют очень «необычные» зависимости и по-разному влияют друг на друга. Вот почему код иногда становится почти не поддерживаемым без ссылок на родителей в каждом случае (иногда даже на нескольких родителей из разных контекстов, т. Е. Отряд может принадлежать к битве, к пользователю и т. Д.).

А теперь причина, по которой ссылки меня не удовлетворяют. Когда я генерирую вывод для клиентской стороны, я использую своего рода сериализацию объектов в XML. Он работает очень хорошо, пока не встретит рекурсивные ссылки, такие как ссылки на родителей. Я могу сделать их защищенными, но тогда они теряют свое использование, т. Е. (Фиктивный пример)

$this->squad->battle->getTeam($tid)->getSquad($sqid)->damageCreature(...);

Другой способ - реализовать метод сериализации в каждом сериализуемом классе и вызвать его внутри сериализатора следующим образом:

$obj->toXML($node);
$this->appendChild($node);

но это много чего можно написать и поддержать! И иногда я динамически генерирую объекты для сериализатора (меньше трафика).

Я даже думаю о взломе: «научить» сериализатор игнорировать некоторые свойства в определенных классах)). Да ... плохая идея ...

Это долгая дискуссия, но поверьте мне, что Registry и Observer не подходят. Есть еще идеи?

0 голосов
/ 16 сентября 2008

Подобно тому, что сказал Павел, если есть только одна буква А, вы можете реализовать ее как одиночку. Затем вы можете передать экземпляр A в качестве аргумента в конструктор (агрегацию) с помощью метода установки (по сути, снова агрегации) или установить это отношение непосредственно в конструкторе (композиция).

Однако, хотя синглтоны являются мощными, будьте осторожны, создавая их с помощью композиции. Приятно думать, что вы можете сделать это таким образом и избавиться от аргумента конструктора, но это также делает невозможным замену A чем-то другим без переписывания кода. Честно говоря, я бы придерживался агрегации, даже если бы использовал синглтон

$foo = new B( A::getInstance() );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...