objects referencing each other - how to implement?

A

Angus Parvis

Hi,

another question: I have some objects, which shall reference each other.
It's a game, and in this game I have planets and players. There's no
planet without a player and no player without a planet. It's essential,
that they both know about each other.

At the moment i'm solving the problem like this:

Player player = new Player();
Planet planet = new Planet(player);
player.setPlanet(planet);

But I don't feel very comfortable about this solution. In my opinion
both Player and Planet should be in a valid state after creation - but
they are not. The user has to know, that the Player.setPlanet()-method
has to be called, to ensure correct behavior.
And what if there are 3 or more objects that have to know about each
other? Does anyone know a good clean and stable approach?

Thanks in advance,

Angus
 
A

Angus Parvis

What do you think of the following: Instead of calling
Player.setPlanet() after the construction of planet, I could call it in
it's constructor. Something like this:

// this code ..
Player player = new Player();
Planet planet = new Planet(player);

// and this constructor ..
class Planet{
public Planet(Player owner) {
owner.setPlanet(this);
// ..
}

//..
}

This would ensure that the planet references the player and the player
the planet.

So, what's your opinion to this solution?
 
A

Anony!

What do you think of the following: Instead of calling
Player.setPlanet() after the construction of planet, I could call it in
it's constructor. Something like this:

// this code ..
Player player = new Player();
Planet planet = new Planet(player);

// and this constructor ..
class Planet{
public Planet(Player owner) {
owner.setPlanet(this);
// ..
}

//..
}

This would ensure that the planet references the player and the player
the planet.

So, what's your opinion to this solution?

class Planet{
Player owner;
public Planet(Player owner){
this.owner = owner;
}
}

likewise with class Player if you want bi-directional communication.

Aaa
 
R

Roedy Green

another question: I have some objects, which shall reference each other.
there is no problem. Java permits forward references. Just compile
both classes at once.
 
A

Angus Parvis

Anony! said:
class Planet{
Player owner;
public Planet(Player owner){
this.owner = owner;
}
}

likewise with class Player if you want bi-directional communication.

Aaa

??? likewise? If A requires B and B requires A, then it's not possible
to please both. Because there's no A without B and no B without an A.

Passing the Planet in the constructor of the Player AND the other way
round is NOT possible.

I'm sorry, but to me your approach is wrong. If it's not, please be so
kind to explain your idea in more detail.

Thx, Angus
 
S

Sebastian Scheid

Angus Parvis said:
What do you think of the following: Instead of calling
Player.setPlanet() after the construction of planet, I could call it in
it's constructor. Something like this:

// this code ..
Player player = new Player();
Planet planet = new Planet(player);

// and this constructor ..
class Planet{
public Planet(Player owner) {
owner.setPlanet(this);
// ..
}

//..
}

This would ensure that the planet references the player and the player
the planet.

So, what's your opinion to this solution?

Good idea. It's the right direction I think :)

What about:

Player {
Planet planet;
Player() {
planet = new Planet(this);
}

Planet getPlanet() {
return planet;
}
}

Planet {
Player player;

Planet(Player player) {
this.player = player;
}
}


The caller can create a new Player and if he wants to work with the Planet
he can get it by calling Player#getPlanet(). For the caller Player and
Planet are in a valid state all the time.

If Planet <-> Player is a 1:N relationship and you have an existing Planet
when creating a new Player for it, you can add the constructor

Player(Planet planet) {
this.planet = planet;
planet.setPlayer(this);
}

to class Player.

Sebastian
 
G

Guest

Angus said:
Hi,

another question: I have some objects, which shall reference each other.
It's a game, and in this game I have planets and players. There's no
planet without a player and no player without a planet. It's essential,
that they both know about each other.

At the moment i'm solving the problem like this:

Player player = new Player();
Planet planet = new Planet(player);
player.setPlanet(planet);

But I don't feel very comfortable about this solution. In my opinion
both Player and Planet should be in a valid state after creation - but
they are not. The user has to know, that the Player.setPlanet()-method
has to be called, to ensure correct behavior.
And what if there are 3 or more objects that have to know about each
other? Does anyone know a good clean and stable approach?

Thanks in advance,

Angus

A couple of symmetric classes
both with a couple of symmetric constructors.

Player {
Planet planet;
Player() {this.planet = new Planet(this);}
Player(Planet planet) {this.planet = planet;}
Planet getPlanet() {return planet;}
}

Planet {
Player player;
Planet () {this.player = new Player(this);}
Planet (Player player) {this.player = player;}
Player getPlayer () {return player;}
}

I love simmetry.
You can hust to instiantiate Players or Planets as you like...

- Dario
 
H

Hemal Pandya

Angus Parvis said:
What do you think of the following: Instead of calling
Player.setPlanet() after the construction of planet, I could call it in
it's constructor. Something like this:

// this code ..
Player player = new Player();
Planet planet = new Planet(player);

// and this constructor ..
class Planet{
public Planet(Player owner) {
owner.setPlanet(this);
// ..
}

//..
}

This is pretty much how I usually do it. But I would call setPlanet at
the end of the constructor. Still, Player.setPlanet needs some
discipline, because the Planet object has not been fully constructed
when that method is called.
 
T

thufir.hawat

On Thu, 29 Jul 2004, [UTF-8] "Dario (drinking coï¬~@ee in the oï¬~Cceâ~@¦)" wrote:
[..]
A couple of symmetric classes
both with a couple of symmetric constructors.

Player {
Planet planet;
Player() {this.planet = new Planet(this);}
Player(Planet planet) {this.planet = planet;}
Planet getPlanet() {return planet;}
}

Planet {
Player player;
Planet () {this.player = new Player(this);}
Planet (Player player) {this.player = player;}
Player getPlayer () {return player;}
}

I love simmetry.
You can hust to instiantiate Players or Planets as you like... ^^^^
????

- Dario

it hurts my brain. I'll google this idea, but I can't think of a concrete
object (dog, etc) which'd require symmetry. The only remotely similar
idea would be if a=b then b=a as a definition for a symetrical relation
(if I have that right).



Thufir Hawat
<http://www.shaw.ca/members/hawat/source/>
 
X

xarax

[..]
A couple of symmetric classes
both with a couple of symmetric constructors.

Player {
Planet planet;
Player() {this.planet = new Planet(this);}
Player(Planet planet) {this.planet = planet;}
Planet getPlanet() {return planet;}
}

Planet {
Player player;
Planet () {this.player = new Player(this);}
Planet (Player player) {this.player = player;}
Player getPlayer () {return player;}
}

I love simmetry.
You can hust to instiantiate Players or Planets as you like...
^^^^
????

- Dario

it hurts my brain. I'll google this idea, but I can't think of a concrete
object (dog, etc) which'd require symmetry. The only remotely similar
idea would be if a=b then b=a as a definition for a symetrical relation
(if I have that right).

I have two classes that each need a final reference to
an instance of the other class. This is a messaging
system between two Java threads. Each instance needs
a reference to the other for send/receiving messages.

I introduced a factory interface type that is used by the
constructor of class A. The class A constructor
calls the factory interface for class B and passes "this"
to the factory method. The factory method calls the class
B constructor with the "this" reference passed by the class A
constructor. The factory method returns the class B reference
which is then assigned to the final field.


public interface FactoryB
{
public abstract B createInstance(A a);
}

public class B
{
protected final A a;

public B(final A theA)
{
super();
a = theA;
}

public A getA()
{
return a;
}

protected static class FactoryBDefault
implements FactoryB;
{
public B createInstance(final A theA)
{
return new B(theA);
}
}

protected static final FactoryB factoryB = new FactoryBDefault();

public static FactoryB getFactoryB()
{
return factoryB;
}
}

public class A
{
protected final B b;

public B getB()
{
return b;
}

public A(final B theB)
{
super();
b = theB;
}

public A(final FactoryB theFactoryB)
{
super();
b = theFactoryB.createInstance(this);
}
}

To instantiate both instances at the same time
with final references to each other:

public class Fubar
{
public static void main(final String[] args)
{
FactoryB factoryB;
A a;
B b;

factoryB = B.getFactoryB();
a = new A(factoryB);
b = a.getB();
}
}


--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!
 
X

xarax

xarax said:
[..]
A couple of symmetric classes
both with a couple of symmetric constructors.

Player {
Planet planet;
Player() {this.planet = new Planet(this);}
Player(Planet planet) {this.planet = planet;}
Planet getPlanet() {return planet;}
}

Planet {
Player player;
Planet () {this.player = new Player(this);}
Planet (Player player) {this.player = player;}
Player getPlayer () {return player;}
}

I love simmetry.
You can hust to instiantiate Players or Planets as you like...
^^^^
????

- Dario

it hurts my brain. I'll google this idea, but I can't think of a concrete
object (dog, etc) which'd require symmetry. The only remotely similar
idea would be if a=b then b=a as a definition for a symetrical relation
(if I have that right).

I have two classes that each need a final reference to
an instance of the other class. This is a messaging
system between two Java threads. Each instance needs
a reference to the other for send/receiving messages.

I introduced a factory interface type that is used by the
constructor of class A. The class A constructor
calls the factory interface for class B and passes "this"
to the factory method. The factory method calls the class
B constructor with the "this" reference passed by the class A
constructor. The factory method returns the class B reference
which is then assigned to the final field.


public interface FactoryB
{
public abstract B createInstance(A a);
}

public class B
{
protected final A a;

public B(final A theA)
{
super();
a = theA;
}

public A getA()
{
return a;
}

protected static class FactoryBDefault
implements FactoryB;

Oops, should be:
implements FactoryB
{
public B createInstance(final A theA)
{
return new B(theA);
}
}

protected static final FactoryB factoryB = new FactoryBDefault();

public static FactoryB getFactoryB()
{
return factoryB;
}
}

public class A
{
protected final B b;

public B getB()
{
return b;
}

public A(final B theB)
{
super();
b = theB;
}

public A(final FactoryB theFactoryB)
{
super();
b = theFactoryB.createInstance(this);
}
}

To instantiate both instances at the same time
with final references to each other:

public class Fubar
{
public static void main(final String[] args)
{
FactoryB factoryB;
A a;
B b;

factoryB = B.getFactoryB();
a = new A(factoryB);
b = a.getB();
}
}


--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!
 
T

thufir.hawat

On Fri, 30 Jul 2004, xarax wrote:
[..]
To instantiate both instances at the same time
^^^^
I don't think it's the same time really, it's consecutive.
with final references to each other:

public class Fubar
{
public static void main(final String[] args)
{
FactoryB factoryB;
A a;
B b;

factoryB = B.getFactoryB();
a = new A(factoryB);
b = a.getB();
}
}
[..]

it appears that the singleton factoryB is the workaround to the "which
came first.." chicken or egg, a or b, mind bender. According to Foobar
"a" is first "because b=a.getB();".

I'm going to take a few more looks, but I've never seen an instance of a
factory before. Admittedly, in the real world there are physical
factories, so again this makes sense, it's just new to me.

In terms of *why* you need to do this I'll have to take your word for it,
I haven't gone that far yet in Java. Thanks for demonstrating a
requirement for symmetry.

Since a has-a factory, now I'm not so sure this's symmetry. In fact, it's
not symmetrical since a has to come first. There's still a chicken-or-egg
paradox, in this case the chicken (a with a factory for b) comes first
with a reproductive system for cranking out eggs (b). giving the egg (b)
a hatching system (factory for a) still doesn't resolve the paradox IMHO.

gets me thinking, thanks!


Thufir Hawat
<http://www.shaw.ca/members/hawat/source/>
 
X

xarax

On Fri, 30 Jul 2004, xarax wrote:
[..]
To instantiate both instances at the same time
^^^^
I don't think it's the same time really, it's consecutive.

When "new A(factoryB)" returns, both instances
are fully instantiated. Don't pick nits with me.
with final references to each other:

public class Fubar
{
public static void main(final String[] args)
{
FactoryB factoryB;
A a;
B b;

factoryB = B.getFactoryB();
a = new A(factoryB);
b = a.getB();
}
}
[..]

it appears that the singleton factoryB is the workaround to the "which
came first.." chicken or egg, a or b, mind bender. According to Foobar
"a" is first "because b=a.getB();".

No, that is just the extraction of the B reference. The B instance
was already inside the A instance (and vice versa) after the call
to "new A(factoryB)" returned. I only used the local variables "a"
and "b" for illustrative purposes.
I'm going to take a few more looks, but I've never seen an instance of a
factory before. Admittedly, in the real world there are physical
factories, so again this makes sense, it's just new to me.

It's a very handy and common design pattern.
In terms of *why* you need to do this I'll have to take your word for it,
I haven't gone that far yet in Java. Thanks for demonstrating a
requirement for symmetry.

Since a has-a factory, now I'm not so sure this's symmetry. In fact, it's
not symmetrical since a has to come first.

In the above example, the factory is provided by A. In my production
code, both classes have factory methods for the other class. In fact,
the factories are provided by other classes altogether. I only included
the factory in A to keep the example simple.
There's still a chicken-or-egg
paradox, in this case the chicken (a with a factory for b) comes first
with a reproductive system for cranking out eggs (b). giving the egg (b)
a hatching system (factory for a) still doesn't resolve the paradox IMHO.

The so-called paradox is resolved by the constructor of one
class instantiating the other class and passing "this" to
the other constructor. The objects don't "officially" exist
until their constructors have all finished, so I have no
philosophical issue with this design pattern regarding
references to "partially constructed" objects being visible
to other "partially constructed" objects. Such objects are
designed to be constructed that way, so there is no problem.

btw: I call it a "design pattern" without reading it anywhere.
It's just a design that works for me in this situation, so I'll
give myself credit for inventing it.

This can be extended to any number co-requisite instantiations.
For example, 3 classes "A", "B", and "C", each of which have final
references to instances of the other two classes.
gets me thinking, thanks!


Thufir Hawat
<http://www.shaw.ca/members/hawat/source/>


--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top