Pattern to avoid circular reference?



 DEVELOP > c-Plus-Plus > Pattern to avoid circular reference?

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "Karthik V"
Date: 06 Dec 2007 10:01:21 PM
Object: Pattern to avoid circular reference?
I've been facing this situation often:
class NewFeature
{
TheClass *theClass;
NewFeature(TheClass *t) { theClass = t; }
void act() { // call methods on theClass }
}
class TheClass
{
NewFeature *feature; // More commonly, a list of NewFeature objects
AddFeature(NewFeature *f) { feature = f; // or append f to a list of
NewFeature objects }
}
In the above case, TheClass class contains pointers to NewFeature
objects, and each NewFeature object contains a pointer to the same
TheClass instance. This does seem to work most of the time but I'm not
comfortable with the idea of this circular reference.
Is there a standard design pattern to overcome this? The closest I saw
was visitor pattern. If I use that here, I'd do something like
class NewFeature
{
TheClass *theClass;
void accept(TheClass *t) { theClass = t; }
void act() { // call methods on theClass }
}
class TheClass
{
AddFeature(NewFeature *f) { f->accept(this); f->act(); }
}
But in this case, I'm losing the ability to keep track of the
NewFeature objects I have. Especially, if NewFeature.act() runs some
thread that calls TheClass methods later, I want TheClass to be able
to start / stop the thread when I want; so maintaining a list of those
pointers will be useful. If I do, I end up having my earlier code.
Please help!
.

User: ""

Title: Re: Pattern to avoid circular reference? 06 Dec 2007 10:35:11 PM
On Dec 6, 10:01 pm, Karthik V <karthikveeram...@gmail.com> wrote:

I've been facing this situation often:

class NewFeature
{
TheClass *theClass;
NewFeature(TheClass *t) { theClass = t; }
void act() { // call methods on theClass }

}

class TheClass
{
NewFeature *feature; // More commonly, a list of NewFeature objects
AddFeature(NewFeature *f) { feature = f; // or append f to a list of
NewFeature objects }

}

In the above case, TheClass class contains pointers to NewFeature
objects, and each NewFeature object contains a pointer to the same
TheClass instance. This does seem to work most of the time but I'm not
comfortable with the idea of this circular reference.

Is there a standard design pattern to overcome this? The closest I saw
was visitor pattern. If I use that here, I'd do something like

class NewFeature
{
TheClass *theClass;
void accept(TheClass *t) { theClass = t; }
void act() { // call methods on theClass }

}

class TheClass
{
AddFeature(NewFeature *f) { f->accept(this); f->act(); }

}

But in this case, I'm losing the ability to keep track of the
NewFeature objects I have. Especially, if NewFeature.act() runs some
thread that calls TheClass methods later, I want TheClass to be able
to start / stop the thread when I want; so maintaining a list of those
pointers will be useful. If I do, I end up having my earlier code.

Please help!

There is nothing wrong with using your method. You have just keeping a
pointer to the object and not the actual object thus you have no
circular reference. All the pointer is in the most general sense is an
integer. Using the actual object would be bad though as this would be
like having a nested class structure and lead to looping in
compilation.
.
User: "Michael DOUBEZ"

Title: Re: Pattern to avoid circular reference? 07 Dec 2007 02:08:27 AM
a écrit :

On Dec 6, 10:01 pm, Karthik V <karthikveeram...@gmail.com> wrote:

I've been facing this situation often:

class NewFeature
{
TheClass *theClass;
NewFeature(TheClass *t) { theClass = t; }
void act() { // call methods on theClass }

}

class TheClass
{
NewFeature *feature; // More commonly, a list of NewFeature objects
AddFeature(NewFeature *f) { feature = f; // or append f to a list of
NewFeature objects }

}

In the above case, TheClass class contains pointers to NewFeature
objects, and each NewFeature object contains a pointer to the same
TheClass instance. This does seem to work most of the time but I'm not
comfortable with the idea of this circular reference.

From a pure design point of view, you are right that it smells. But
sometimes, it is the more natural way of doing rather than go through
complex construction.
This often happen, as in your case a class owning a feature, when an
object has to keep a pointer on the object that owns it. The only
difficulty is lifetime issues: making the difference when a object is
destroyed by the object that own its or by other mean; there are many
strategy to adresse that.

Is there a standard design pattern to overcome this? The closest I saw
was visitor pattern.

Visitor tends to increase coupling between classes. I am pretty sure it
is not what you want.
The right solution greatly depends on what you want to achieve and the
environment you work in.
A generic solution (not the best for you) is defining an interface class
that is taken in parameter by a NewFeature. TheClass would inherit from
this interface and pass itself in parameter to the NewFeature.

If I use that here, I'd do something like

class NewFeature
{
TheClass *theClass;
void accept(TheClass *t) { theClass = t; }
void act() { // call methods on theClass }

}

class TheClass
{
AddFeature(NewFeature *f) { f->accept(this); f->act(); }

}

But in this case, I'm losing the ability to keep track of the
NewFeature objects I have. Especially, if NewFeature.act() runs some
thread that calls TheClass methods later, I want TheClass to be able
to start / stop the thread when I want; so maintaining a list of those
pointers will be useful. If I do, I end up having my earlier code.

You could also lookup "observer pattern" and signal/slot idiom. You
could also split your classes; it seems to me that TheClass has a lot of
responsibilities :start/stop thread, provides functions called into the
thread.
I can't help you there, it is your design.



There is nothing wrong with using your method. You have just keeping a
pointer to the object and not the actual object thus you have no
circular reference. All the pointer is in the most general sense is an
integer. Using the actual object would be bad though as this would be
like having a nested class structure and lead to looping in
compilation.

The OP problem is not from a compilation point of view but rather a
design issue.
Michael
.
User: "Karthik V"

Title: Re: Pattern to avoid circular reference? 07 Dec 2007 11:29:31 AM
On Dec 7, 12:08 am, Michael DOUBEZ <michael.dou...@free.fr> wrote:

adam.mad...@gmail.com a =E9crit :



On Dec 6, 10:01 pm, Karthik V <karthikveeram...@gmail.com> wrote:

I've been facing this situation often:


class NewFeature
{
TheClass *theClass;
NewFeature(TheClass *t) { theClass =3D t; }
void act() { // call methods on theClass }


}


class TheClass
{
NewFeature *feature; // More commonly, a list of NewFeature objects
AddFeature(NewFeature *f) { feature =3D f; // or append f to a list o=

f

NewFeature objects }


}


In the above case, TheClass class contains pointers to NewFeature
objects, and each NewFeature object contains a pointer to the same
TheClass instance. This does seem to work most of the time but I'm not
comfortable with the idea of this circular reference.


From a pure design point of view, you are right that it smells. But
sometimes, it is the more natural way of doing rather than go through
complex construction.

This often happen, as in your case a class owning a feature, when an
object has to keep a pointer on the object that owns it. The only
difficulty is lifetime issues: making the difference when a object is
destroyed by the object that own its or by other mean; there are many
strategy to adresse that.

Is there a standard design pattern to overcome this? The closest I saw
was visitor pattern.


Visitor tends to increase coupling between classes. I am pretty sure it
is not what you want.

The right solution greatly depends on what you want to achieve and the
environment you work in.
A generic solution (not the best for you) is defining an interface class
that is taken in parameter by a NewFeature. TheClass would inherit from
this interface and pass itself in parameter to the NewFeature.



If I use that here, I'd do something like


class NewFeature
{
TheClass *theClass;
void accept(TheClass *t) { theClass =3D t; }
void act() { // call methods on theClass }


}


class TheClass
{
AddFeature(NewFeature *f) { f->accept(this); f->act(); }


}


But in this case, I'm losing the ability to keep track of the
NewFeature objects I have. Especially, if NewFeature.act() runs some
thread that calls TheClass methods later, I want TheClass to be able
to start / stop the thread when I want; so maintaining a list of those
pointers will be useful. If I do, I end up having my earlier code.


You could also lookup "observer pattern" and signal/slot idiom. You
could also split your classes; it seems to me that TheClass has a lot of
responsibilities :start/stop thread, provides functions called into the
thread.
I can't help you there, it is your design.



There is nothing wrong with using your method. You have just keeping a
pointer to the object and not the actual object thus you have no
circular reference. All the pointer is in the most general sense is an
integer. Using the actual object would be bad though as this would be
like having a nested class structure and lead to looping in
compilation.


The OP problem is not from a compilation point of view but rather a
design issue.

Michael

Michael and Adam,
Thanks a lot! As Michael said, the main concern was destroying the
object. Since the NewFeature can be extended and implemented by
anyone, there is a potential possibility of that code invoking a
Destroy() on TheClass. I was wondering if there is a way to prevent
that.
Michael, the way I have it now, TheClass is just an interface, not the
concrete implementation. So I guess I'm following that practice
already.
.
User: "Michael DOUBEZ"

Title: Re: Pattern to avoid circular reference? 08 Dec 2007 03:47:51 PM
Karthik V a écrit :

Michael and Adam,

Thanks a lot! As Michael said, the main concern was destroying the
object. Since the NewFeature can be extended and implemented by
anyone, there is a potential possibility of that code invoking a
Destroy() on TheClass. I was wondering if there is a way to prevent
that.

Declare the destructor of TheClass protected.


Michael, the way I have it now, TheClass is just an interface, not the
concrete implementation. So I guess I'm following that practice
already.

Michael
.
User: "terminator"

Title: Re: Pattern to avoid circular reference? 09 Dec 2007 05:48:12 AM
On Dec 9, 12:47 am, Michael DOUBEZ <michael.dou...@free.fr> wrote:

Karthik V a =E9crit :

Michael and Adam,


Thanks a lot! As Michael said, the main concern was destroying the
object. Since the NewFeature can be extended and implemented by
anyone, there is a potential possibility of that code invoking a
Destroy() on TheClass. I was wondering if there is a way to prevent
that.


Declare the destructor of TheClass protected.



Michael, the way I have it now, TheClass is just an interface, not the
concrete implementation. So I guess I'm following that practice
already.


Michael

why not to refrence count 'TheClass'(e.g using boost::shared_ptr)?
regards,
FM.
.
User: "James Kanze"

Title: Re: Pattern to avoid circular reference? 09 Dec 2007 07:34:50 AM
On Dec 9, 12:48 pm, terminator <farid.mehr...@gmail.com> wrote:

On Dec 9, 12:47 am, Michael DOUBEZ <michael.dou...@free.fr> wrote:

Karthik V a =E9crit :

Michael and Adam,
Thanks a lot! As Michael said, the main concern was destroying the
object. Since the NewFeature can be extended and implemented by
anyone, there is a potential possibility of that code invoking a
Destroy() on TheClass. I was wondering if there is a way to prevent
that.

Declare the destructor of TheClass protected.

Michael, the way I have it now, TheClass is just an interface, not the=
concrete implementation. So I guess I'm following that practice
already.

why not to refrence count 'TheClass'(e.g using boost::shared_ptr)?

What does that solve (except introduce a lot of constraints in
the use of TheClass).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34
.




User: "James Kanze"

Title: Re: Pattern to avoid circular reference? 09 Dec 2007 07:33:19 AM
On Dec 7, 9:08 am, Michael DOUBEZ <michael.dou...@free.fr> wrote:

adam.mad...@gmail.com a =E9crit :

On Dec 6, 10:01 pm, Karthik V <karthikveeram...@gmail.com> wrote:

I've been facing this situation often:
class NewFeature
{
TheClass *theClass;
NewFeature(TheClass *t) { theClass =3D t; }
void act() { // call methods on theClass }
}
class TheClass
{
NewFeature *feature; // More commonly, a list of NewFeature objects
AddFeature(NewFeature *f) { feature =3D f; // or append f to a list o=

f

NewFeature objects }
}
In the above case, TheClass class contains pointers to NewFeature
objects, and each NewFeature object contains a pointer to the same
TheClass instance. This does seem to work most of the time but I'm not
comfortable with the idea of this circular reference.

From a pure design point of view, you are right that it smells. But
sometimes, it is the more natural way of doing rather than go through
complex construction.

Why? It looks like a more or less standard implementation of
the strategy pattern. Most of the time, the strategy
elements---the NewFeature here---don't need a reference to the
parent, but I don't see any particular problem when they do.
Most of the time, of course, NewFeature will be an abstract base
class; in such cases, it's often simplest to make it a member
class of TheClass. (Not that this changes much in overall
view.)

This often happen, as in your case a class owning a feature,
when an object has to keep a pointer on the object that owns
it. The only difficulty is lifetime issues: making the
difference when a object is destroyed by the object that own
its or by other mean; there are many strategy to adresse that.

The usual solution is to have the TheClass construct the
NewFeature, via some special function, and then own it, deleting
it in its destructor.

Is there a standard design pattern to overcome this? The
closest I saw was visitor pattern.

Visitor tends to increase coupling between classes. I am
pretty sure it is not what you want.

I don't think it's what he's looking for either, but not because
of coupling. In his case, the coupling is there (since
NewFeature depends on TheClass).
In the past, I've used a variant of this several times, in which
NewFeature was an abstract base class, member and friend of
TheClass, and it provided an extended interface to TheClass, so
that user code could implement a wide variety of strategies.

If I use that here, I'd do something like


class NewFeature
{
TheClass *theClass;
void accept(TheClass *t) { theClass =3D t; }
void act() { // call methods on theClass }
}
class TheClass
{
AddFeature(NewFeature *f) { f->accept(this); f->act(); }
}
But in this case, I'm losing the ability to keep track of
the NewFeature objects I have.

If the NewFeature objects are polymorphic (and I don't see very
well how they could not be), then in practice, they'll all be
allocated on the stack. The usual solution in my code is just
to let the garbage collector take care of them, but if for some
reason you cannot use garbage collection, it's typically not too
much of a constraint to require them to be unique to each
instance, and have TheClass take over ownership, and delete them
in the destructor. (I'd document this by having the function
which registers them take an auto_ptr.) Some sort of reference
counting could also be used, but typically, it's overkill.

Especially, if NewFeature.act() runs some thread that calls
TheClass methods later, I want TheClass to be able to start
/ stop the thread when I want; so maintaining a list of
those pointers will be useful. If I do, I end up having my
earlier code.

If the NewFeature uses worker threads, you have a whole lot of
additional issues to address. Like what happens if the TheClass
object is deleted before the worker thread has finished.
One solution I've used at times is to make the destructor of
TheClass private, and require calling a special member function
to destroy the object. This function marks the object as
"dead", and puts it on a queue for destruction; actual
destruction only occurs when the last worker thread has
finished. It's not a universal solution, however, and isn't
always appropriate.
(Trying to do multithreading without garbage collection is just
plain stupid.)

You could also lookup "observer pattern" and signal/slot
idiom. You could also split your classes; it seems to me that
TheClass has a lot of responsibilities :start/stop thread,
provides functions called into the thread. I can't help you
there, it is your design.

Making the observer pattern work well between threads is far
from trivial.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34
.




  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER