tags:

views:

3161

answers:

5

An instance of class A instanciates a couple of other objects, say for example from class B:

$foo = new B();

I would like to access A's public class variables from methods within B.

Unless I'm missing something, the only way to do this is to pass the current object to the instances of B:

$foo = new B($this);

Is this best practice or is there another way to do this?

+1  A: 

I would first check if you are not using the wrong pattern: From your application logic, should B really know about A? If B needs to know about A, a parent-child relationship seems not quite adequate. For example, A could be the child, or part of A's logic could go into a third object that is "below" B in the hierarchy (i. e. doesn't know about B).

That said, I would suggest you have a method in B to register A as a data source, or create a method in A to register B as an Observer and a matching method in B that A uses to notify B of value changes.

Hanno Fietz
+2  A: 

That looks fine to me, I tend to use a rule of thumb of "would someone maintaining this understand it?" and that's an easily understood solution.

If there's only one "A", you could consider using the registry pattern, see for example http://www.phppatterns.com/docs/design/the_registry

Paul Dixon
Thank you. In my particular case the registry pattern applies indeed. (Class A open several database links and has to pass configuration information to B and other classes.)
christian studer
A: 

Observer Pattern should work best i think

DeeCee
A: 

Similar to what Paul said, if there's only one A, you can implement that as a singleton. You can then pass the instance of A as an argument to the constructor (aggregation), with a setter method (essentially aggregation again), or you can set this relationship directly in the constructor (composition).

However, while singletons are powerful, be wary of implementing them with composition. It's nice to think that you can do it that way and get rid of a constructor argument, but it also makes it impossible to replace A with something else without a code rewrite. Peronsally, I'd stick with aggregation, even if using a singleton

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

Code like this unfortunately does not match my needs. Is there any other way to access the parent object properties?

I'll try to explain why. We write a game software and some classes have very "unusual" dependencies and influence each other in different ways. That's why code sometimes gets almost unsupportable without links to parents in every instance (sometimes even several parents from different contexts i.e. a Squad may belong to Battle and to User etc...).

And now the reason why links don't satisfy me. When I generate an output for the client side, I use a kind of serializing objects in XML. It works very nice until it meets recursive references like those links to parents. I can make them protected, but then they loose their usage i.e. (dummy example)

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

The other way - to implement serialization method in every serializable class and call it inside serializer like this:

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

but that's a lot of stuff to write and to support! And sometimes i generate the objects for serializer dynamically (less traffic).

I even think about a hack: to "teach" serializer to ignore some properties in certain classess )). Huh... bad idea...

It's a long discussion, but believe me, that Registry and Observer don't fit. Are there any other ideas?

Jet