doubly linked objects

A

Andersen

Is there an idiom or pattern for creating two objects (a and b) of two
different classes A and B, such that A contains a reference to b and B
contains a reference to a. Should I pass it through a constructor? In
that case, when creating A, I cannot give the constructor a reference to
b since b has not yet been created (or vice versa if b is created first).

Should I have set methods in both where I can set these variables? Then
I have the problem that one might forget to set it, and the object is in
a bad state.

regards,
Andersen
 
R

Robert Klemme

Andersen said:
Is there an idiom or pattern for creating two objects (a and b) of two
different classes A and B, such that A contains a reference to b and B
contains a reference to a. Should I pass it through a constructor? In
that case, when creating A, I cannot give the constructor a reference
to b since b has not yet been created (or vice versa if b is created
first).

Should I have set methods in both where I can set these variables?
Then I have the problem that one might forget to set it, and the
object is in a bad state.

It depends... My first choice would be to have property accessors
(get/set) on both sides implemented in a way that they keep the other side
updated.

robert
 
A

Andersen

Robert said:
It depends... My first choice would be to have property accessors
(get/set) on both sides implemented in a way that they keep the other side
updated.

There must be an idiom or a pattern for achieving this. I mean, what if
a client simply forgets to call the set method. I would have to add
asserts *everywhere* in A and B where this reference is called. Not very
pleasant.

Maybe a static factory which creates both, and make the other
constructors (A and B) private to ensure that clients pass through the
static factory, which in turns ensures that the proper set methods are
called.

What to do? please help.

regards,
Andersen
 
O

Oliver Wong

Andersen said:
Is there an idiom or pattern for creating two objects (a and b) of two
different classes A and B, such that A contains a reference to b and B
contains a reference to a. Should I pass it through a constructor? In that
case, when creating A, I cannot give the constructor a reference to b
since b has not yet been created (or vice versa if b is created first).

Should I have set methods in both where I can set these variables? Then I
have the problem that one might forget to set it, and the object is in a
bad state.

I posted a reply to this in comp.lang.java.help.

- Oliver
 
T

Thomas G. Marshall

Oliver Wong coughed up:
I posted a reply to this in comp.lang.java.help.

This question was fine where it was. It is not a java-newbie question at
all---this is the kind of question that you might find in comp.object.
 
A

Andrew McDonagh

Thomas said:
Oliver Wong coughed up:



This question was fine where it was. It is not a java-newbie question at
all---this is the kind of question that you might find in comp.object.

+1 vote
 
T

Thomas G. Marshall

Andrew McDonagh coughed up:

I think that Oliver might have said this because of a multi-post to .help
that the OP had already placed.

Dunno.
 
R

Roedy Green

There must be an idiom or a pattern for achieving this. I mean, what if
a client simply forgets to call the set method. I would have to add
asserts *everywhere* in A and B where this reference is called. Not very
pleasant.

In other words you want an iron clad guarantee that objects are not
visible to the outside world until they have their links built.
Obviously for some short time they must be incomplete. You can't find
out the address of B to feed to A before B exists and you can't create
B until you have the address of A.

If you promote A to Aprime it will get a new address, so staging by
using a builder object that gets converted when it is ready to the
actual object by a constructor does not look promising.

A reasonable but not unbreakable approach is to use a factory to
create a pair of objects. You can make A and B abstract , or the
constructors private, hand out only an Interface and give the classes
themselves some horrible name.


You could have an "activated" boolean which is turned on when you use
the :
link ( A a , B b ) method tha builds both links.

You assert that boolean is turned on in crucial methods.

You could explicitly assert the link to the other is not null in
crucial methods.
 
A

Andersen

Thomas said:
I think that Oliver might have said this because of a multi-post to .help
that the OP had already placed.

Right. My apologies, should have only posted it here (and perhaps to
comp.object).
 
J

Jon Martin Solaas

Andersen said:
Is there an idiom or pattern for creating two objects (a and b) of two
different classes A and B, such that A contains a reference to b and B
contains a reference to a. Should I pass it through a constructor? In
that case, when creating A, I cannot give the constructor a reference to
b since b has not yet been created (or vice versa if b is created first).

Should I have set methods in both where I can set these variables? Then
I have the problem that one might forget to set it, and the object is in
a bad state.

regards,
Andersen

If you want to initialize via constructor or setXXX depends on the usage
pattern. If the relationship is to be "immutable" (ie. you don't need to
change the references after construction), use constructor only, if you
need to change later on use setXXX, or both.

To solve your chicken-and-egg problem, just let A create new B if the B
parameter of A constructor is null (and vice versa ...).

Using constructor initialization (and have default constructor without
params private) will prevent the dozy programmer from screwing up.
 
R

Robert Klemme

Andersen said:
There must be an idiom or a pattern for achieving this. I mean, what
if a client simply forgets to call the set method. I would have to add
asserts *everywhere* in A and B where this reference is called. Not
very pleasant.

Maybe a static factory which creates both, and make the other
constructors (A and B) private to ensure that clients pass through the
static factory, which in turns ensures that the proper set methods are
called.

If they are so tightly coupled then why not create one instance in the
other instance's constructor? As I said, it all depends on the model
you're trying to implement and the intended usage.

Regards

robert
 
L

Lasse Reichstein Nielsen

Andersen said:
Is there an idiom or pattern for creating two objects (a and b) of two
different classes A and B, such that A contains a reference to b and B
contains a reference to a.

What is the role of A and B? How are they used? Is one of them usually
accessed through the other? Are A and B in the same package?

If they always have a single reference to each other, why is it not
just one class? Or can the reference change?

Do they take (other) arguments to their constructors?


Depending on the answers to these questions, I see three solutions (at
least):
1. Create one of them in the other class' constructor, passing the
an instance to the second constructor.

2. Create one object and then make two views of it, with A and B being
interfaces.

3. Use setters and allow changes to the reference.

/L
 
T

Thomas Hawtin

Andersen said:
There must be an idiom or a pattern for achieving this. I mean, what if
a client simply forgets to call the set method. I would have to add
asserts *everywhere* in A and B where this reference is called. Not very
pleasant.

I have seen released code that requires an initialisation call after
every call to a constructor. In one or two cases the initialisation was
left out. It doesn't matter so much in a framework situation, where
there are many implementation and few places that construct.



For two object to have final references to each other the two obvious
solutions are make one an inner class of the other or create one in the
constructor of another.

You might want to step back a bit and decouple them slightly. Perhaps
one should add a listener to the other. Or perhaps it can be
restructured to introduce a third object that takes up aspects of both A
and B.

Tom Hawtin
 
O

Oliver Wong

Andersen said:
Right. My apologies, should have only posted it here (and perhaps to
comp.object).

Yes, I didn't mean to imply "This discussion should be moved to .help!"
or anything like that. It just so happened that I saw the original post in
..help, posted a reply, and then saw it here. Rather than copy and paste my
original reply, I just gave a reference to it.

- Oliver
 
A

Andrea Desole

Lasse said:
What is the role of A and B? How are they used? Is one of them usually
accessed through the other? Are A and B in the same package?

If they always have a single reference to each other, why is it not
just one class? Or can the reference change?

Do they take (other) arguments to their constructors?

I was thinking of similar questions. I would like to see a real example,
because this relationship between A and B, as I understand it, looks
unusual.
 
A

Andrew McDonagh

Andersen said:
Is there an idiom or pattern for creating two objects (a and b) of two
different classes A and B, such that A contains a reference to b and B
contains a reference to a. Should I pass it through a constructor? In
that case, when creating A, I cannot give the constructor a reference to
b since b has not yet been created (or vice versa if b is created first).

Should I have set methods in both where I can set these variables? Then
I have the problem that one might forget to set it, and the object is in
a bad state.

regards,
Andersen

The Factory pattern described by several posters is appropriate here,
but the are alternatives - there's never a single answer.

You say that A & B must reference each other and you want to protect
others from creating them incorrectly.

One way to achieve this is to make A & B non-public inner classes of
another class which is used everywhere.

Because they are inner classes, only their parent can instantiate them,
and so has full control.

Its kind of like the factory approach, but different. The main outer
class has its own responsibility, which is not to be a factory for
correctly instantiated As & Bs. The mere fact that it does do that, is
an implementation detail of that outer class. Its encapsulated.

There are other approaches and some over lap each other.

Andrew
 
R

Richard Wheeldon

Andrea said:
I was thinking of similar questions. I would like to see a real example,
because this relationship between A and B, as I understand it, looks
unusual.

java.io.PipedOutputStream
java.io.PipedInputStream

One cannot usefully exist without the other,

Richard
 
A

Andrea Desole

Richard said:
java.io.PipedOutputStream
java.io.PipedInputStream

One cannot usefully exist without the other,

I'm not sure this is what the OP meant. Although it's true that you need
both, it's also true that you don't have to call one stream's
constructor giving the other one as parameter. Nor you have to call a
setter. The fact that the classes are in the same package makes it
easier for them to communicate with each other transparently
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top