The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Objects passing themselves to other objects

Is there anything wrong with an object passing itself to other objects, if those other objects are contained within the first object?

In other words, I have an object X that manages a collection of Y objects. There are some methods in the Y objects, that need to know something about their position in the collection, or about the rest of the collection.

Is it appropriate to pass X into those methods, since X is the only object that has that information? Or is this a bad design? The alternatives I can think of are:

1) put any such methods in X, even if they make more sense in the context of Y. This seems to unnecessarily inflate X.

2) have X keep all the Y objects updated with their position in the collection, so they don't have to ask X about it.

What do you think?
JW
Monday, April 16, 2007
 
 
I'm a little uneasy about Y needing to know about being in a collection, but apart from that, there's nothing wrong with passing yourself to another object so it can ask you things about yourself.
Mike S Send private email
Monday, April 16, 2007
 
 
Yeah, in a perfect world there wouldn't be that tight of coupling, but there are a million reasons why sometimes its the solutoin that is the least messy.
Vincent Send private email
Monday, April 16, 2007
 
 
I consider this a bad design. The Y should never need to know X.

Consider putting these methods into X, or standline functions  /function classes.
Glitch
Monday, April 16, 2007
 
 
I do that often (not usually: but often). It's especially not inappropriate when Y might be a nested class or friend of X.

> I'm a little uneasy about Y needing to know about being in a collection

Some things are born to exist in a collection: the XmlNode class for example has a Parent property.

> Consider putting these methods into X, or standline functions /function classes.

That inflates the X interface. Also if you have a method like ...

class X
{
 List<Y> children = ...;
 Point getPositionOfChild(Y child) { ... }
}

... then you run the risk of someone passing-in a Y instance that isn't a child of this X.
Christopher Wells Send private email
Monday, April 16, 2007
 
 
In general, cyclical depencencies are bad (which one do you compile first?)

Look up the "Dependency Inversion Principle", where X can depend on Y, Y Depends on -interface- Z, and X implements Z.  (There is a LOT more to it, but that's the basic concept).
Another Anonymous Coward
Monday, April 16, 2007
 
 
This is useful for asynchronous callbacks, where you can't keep the caller blocked in the method. You'll want to program towards an interface which just exposes callback method, rather then giving access to all of the object's features.

This is also necessary to implement a vistor pattern, which imho one should try to rarely use.

Either way, always program towards an interface in this situation. You'll want to limit the damage of coupling.
Manes
Monday, April 16, 2007
 
 
Thanks for the suggestions so far. When I started this design, I had looked at an article on Dependency Inversion and Inversion of Control (http://www.objectmentor.com/resources/articles/dip.pdf), but I'm not sure I was able to completely connect it to my situation.

It sounds like the basic idea is, when in this kind of situation, to insert an interface in between the two layers. In my example, X contains a collection of Ys, and I had a method y.something(X x), which y used to find out about other ys in the collection.

So if I insert an interface I, then I would have X implement I, and the method in Y would be y.something(I i) instead. Is that a better approach? At least it seems to limit the circularity.
JW
Monday, April 16, 2007
 
 
Also, if X is the only collection of Ys that makes sense in my situation, is it worth the added confusion to insert this interface in between them? I can imagine wondering later on why I bothered passing an I, when I could have just passed an X.
JW
Monday, April 16, 2007
 
 
If X is the only collection of Ys that makes sense in my situation then class Y can (and probably should) be nested within class X, thus making the coupling explicit. If you never see Y outside the context of X, then it's ok. If you can have a Y floating off on its own, then a year later you will forget that every Y has to be held inside an X.

Monday, April 16, 2007
 
 
Often a container and the things contained need to work together, so I don't consider it bad design at all. It's like a child window not being able to ask it's parent where it's X, Y coordinates are. Does that make sense?

It's better not to have this relationship, it's better not the have cyclic dependencies, but they are often necessary. I can't see how stuffing the same calls into a function or imposing an interface that doesn't really represent anything as better.
son of parnas
Tuesday, April 17, 2007
 
 
If the purpose of Y's existence is only to exist in a collection managed by X, and Y is not a general type you might use elsewhere for other things, then I don't see any problem with this pattern.

Better in fact would be to pass the reference to X in the constructor of Y so that each Y knows which X it belongs to, and you need not pass in the reference in the method call on Y. This only works if each Y can only belong to and operate on a particular X, of course. If you were doing a parent / child tree structure, this would be exactly what you'd do (someone mentioned the XmlNode earlier, which is a prime example).

If you can see that you might at some point want to have a collection of Z on X rather than Y, then an interface makes more sense.
.NET Guy
Tuesday, April 17, 2007
 
 
I would recommend that the collection class X be given the responsibility for managing all things related to the collection organization.  If I were doing the design, I would prefer that my lower level classes (Y) do not require knowledge that they might be placed in a collection.

Sorting or other sorts of operations between two members of a collection should be done at the collection level.  I wouldn't be concerned about "bloated" code in the collection; in my expereince, I see far too little code delegated to collection-type classes.

Either solution is workable.  Barring other detailed information, I would recommend your approach to place the functions in your collection class.  I am guessing this will result in better organization in the long run.
Wayne M.
Tuesday, April 17, 2007
 
 
In general there is nothing wrong with an object passing itself to another object. However in this case I think there are a few red flags about the design.

It's going to cause trouble somewhere if an object needs to know its position in a collection. Whatever Y does that needs to about its position should be made the responsibility of the collection (or the class that contains the collection). If that's technically impossible then have X collect the information that each Y needs about its position and pass it to Y as arguments.

Both your two approaches are viable. I think one of the points is that if the methods need to know about position in the collection, then they DON'T make more sense in the context of Y - they only seem so.
DJC
Tuesday, April 17, 2007
 
 
"If the purpose of Y's existence is only to exist in a collection managed by X, and Y is not a general type you might use elsewhere for other things, then I don't see any problem with this pattern.

Better in fact would be to pass the reference to X in the constructor of Y so that each Y knows which X it belongs to, and you need not pass in the reference in the method call on Y." --.NET Guy

.NET Guy is spot on with this reply.
When you encounter that kind of situation I advice you to make Y an inner class of X.
Java has tackled this particular design problem in an Interesting way : by default an inner class ALWAYS has a reference to the outer class! Inner class (Y) MUST be instanciated trough an INSTANCE of the outer class (X).  So in any inner class in Java you can always do "TheOuterClassName.this" to get the instance of the outer class.

In .NET you can emulate this by passing yourself a reference of X to Y.

If you want to learn more about this there is a funny story about it http://www.javaranch.com/campfire/StoryInner.jsp (just remember that in .NET all inner classes are the equivalent of the static innner classes in Java, that is, there is no special relations between objects of the outer and objects of the inner class).


I don't agree with the people who say that it's a bad design. Yes the collection and the item both have a reference to the other one. So what? If they need that relationship, artificially removing it will only make things uglier.
Monkeyget Send private email
Wednesday, April 18, 2007
 
 
> When you encounter that kind of situation I advice you to make Y an inner class of X.

As long as they are in the same package and I don't think you need to make it an inner class. To me this just complicates things as classes become too big.
son of parnas
Wednesday, April 18, 2007
 
 
In my software (A CAD/CAM package) I have a object called Shapes that has a list of generic properties called Entries. I have a Shape Program Object implementing IShapeProgram.

Each shape has a shapeprogram. Each shapeprogram has a shape that it gets and sets data on.

To avoid the problem of doubly linked objects.I use a shapeproxy object. Each shape can emit a shapeproxy which is tied through the langauge event mechanism. The ShapeProgram parent is set to the shapeproxy not the shape itself.

This avoids the doubly linked problem. When the shapeproxy fires the event the shape is either there or not there. If not there then it returns nothing/nil/null.

Wednesday, April 18, 2007
 
 
I like the suggestion to use inner classes. Unfortunately my language (PHP) doesn't support them.

I also like the suggestion to create the children by passing a reference to the parent to their constructor. However, I happen to be creating the children during the *parent's* constructor. I'm not sure it's good form (or allowed) to pass a reference to yourself before you've been fully constructed.

That's why I'm still (at this point) passing the parent to the children's methods.
JW
Wednesday, April 18, 2007
 
 
"I'm not sure it's good form (or allowed) to pass a reference to yourself before you've been fully constructed."

You can do that but the children objects need to be careful not to access any uninitialized fields of the parent object.
Frederik Slijkerman
Thursday, April 19, 2007
 
 
I myself always like to add a property in Y something called "Owner" or "Parent" and assign it with X in the constructor of Y (that's to say, you may take X object as a parameter of Y's constructor).
Then Y can use that property to do anything it want.

Adding that kind of property is reasonable because X is the holder of Y, so we can say X is Y's owner or parent.
The son has the right to know who is his parent. LOL.

The most ideal way is Y should never know X, but the true-life is not always perfectly ideal.
Koms Bomb Send private email
Thursday, April 19, 2007
 
 
There is nothing wrong with passing objects to objects.

Ideally you should use interfaces.

There are several approaches, construction injection, setter injection, etc... (as mentioned, try reading about Dependency Injection)

http://www.martinfowler.com/articles/injection.html

Class A : SomeInterface

Class B
private SomeInterface aInterface;
public B(SomeInterface interface)  //ctor injection
{
 aInterface= interface;
}


Perfectly acceptable.
Steve
Friday, April 27, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz