2008-09-15 15 views
2

Une instance d'une classe instancie deux autres objets, disons par exemple de la classe B:Comment accéder aux variables de classe d'un objet parent en PHP?

$foo = new B(); 

Je voudrais accéder à des variables de classe publiques A partir de méthodes au sein B.

À moins que je suis manque quelque chose, la seule façon de le faire est de passer l'objet courant aux instances de B:

$foo = new B($this); 

est-ce la meilleure pratique ou est-il une autre façon de le faire?

Répondre

2

Cela me semble bien, j'ai tendance à utiliser une règle de base de "quelqu'un qui maintient cela comprendrait-il?" et c'est une solution facilement comprise.

S'il n'y a qu'un seul « A », vous pourriez envisager d'utiliser le modèle de registre, voir par exemple http://www.phppatterns.com/docs/design/the_registry

+0

Merci. Dans mon cas particulier, le modèle de registre s'applique en effet. (La classe A ouvre plusieurs liens de base de données et doit transmettre des informations de configuration à B et à d'autres classes.) –

1

Je vérifie d'abord si vous n'utilisez pas le mauvais modèle: D'après votre logique d'application, B devrait-il vraiment connaître A? Si B a besoin de savoir sur A, une relation parent-enfant ne semble pas tout à fait adéquate. Par exemple, A pourrait être l'enfant, ou une partie de la logique de A pourrait aller dans un troisième objet qui est «en dessous» de B dans la hiérarchie (c'est-à-dire qui ne connaît pas B). Cela dit, je suggère que vous ayez une méthode dans B pour enregistrer A comme une source de données, ou créer une méthode dans A pour enregistrer B comme Observer et une méthode correspondante dans B que A utilise pour notifier B de valeur changements.

0

similaires à ce que Paul a dit, s'il n'y a qu'un seul A, vous pouvez mettre en œuvre que comme un singleton. Vous pouvez ensuite passer l'instance de A comme argument au constructeur (agrégation), avec une méthode setter (essentiellement à nouveau l'agrégation), ou vous pouvez définir cette relation directement dans le constructeur (composition).

Cependant, tandis que les singletons sont puissants, méfiez-vous de les mettre en œuvre avec la composition. C'est agréable de penser que vous pouvez le faire de cette façon et de vous débarrasser d'un argument constructeur, mais cela rend également impossible de remplacer A par quelque chose d'autre sans une réécriture de code. Peronsally, je bâton avec l'agrégation, même si vous utilisez un singleton

$foo = new B(A::getInstance()); 
0
$foo = new B($this); 

code comme celui-ci ne correspond malheureusement pas à mes besoins. Existe-t-il un autre moyen d'accéder aux propriétés de l'objet parent?

Je vais essayer d'expliquer pourquoi. Nous écrivons un logiciel de jeu et certaines classes ont des dépendances très "inhabituelles" et s'influencent mutuellement de différentes manières. C'est pourquoi le code devient parfois presque insupportable sans liens avec les parents dans tous les cas (parfois même plusieurs parents de différents contextes, c'est-à-dire une escouade peut appartenir à Battle et à l'utilisateur etc ...).

Et maintenant la raison pour laquelle les liens ne me satisfont pas. Lorsque je génère une sortie pour le client, j'utilise une sorte d'objets sérialisants en XML. Cela fonctionne très bien jusqu'à ce qu'il rencontre des références récursives comme ces liens aux parents. Je peux les protéger, mais ils perdent leur usage, c'est-à-dire(Exemple fictif)

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

L'autre façon - de mettre en œuvre la méthode de sérialisation dans toutes les classes sérialisable et l'appeler à l'intérieur sérialiseur comme ceci:

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

mais qui est beaucoup de choses à écrire et à soutenir! Et parfois, je génère dynamiquement les objets pour le sérialiseur (moins de trafic).

Je pense même à un hack: pour "apprendre" le sérialiseur à ignorer certaines propriétés dans certains classess)). Huh ... mauvaise idée ...

C'est une longue discussion, mais croyez-moi, le registre et l'observateur ne correspondent pas. Y a-t-il d'autres idées?

Questions connexes