C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Visitor Pattern Choices
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Merlin
Guest





PostPosted: Thu Dec 29, 2005 12:18 pm    Post subject: Visitor Pattern Choices Reply with quote



Probably there is no right or wrong answer to this but I thought to ask
to put my mind at rest. Ok lets say you have a object hierarchy (eg.
the Glyph in Lexi from GOF book) and you want to use the visitor
pattern. So we place an accept method in the the base class glyph and
procede to create the visitor hierarchy. The accept signature will look
like this

void Glyph::Accept(Visitor& v);

The Visitor hierarchy will have a Vistor base class that will have a
visit method for each different type of Glyph so say if we have an
AssignnentNode and VariableNode there will be two methods

void visit(AssignnentNode& n);
void visit(VariableNode & n);

and in each concrete visitor we implement these methods to behave as we
wish. So far so good...

Imagine you think of 20 different types of operations that you like to
perform on your object structure and u like to use the Visitor pattern
to do this. So you create 20 different classes each implementing the
visitor interface.

Should we inherit all these 20 classes from our visitor base class? If
so this means a single Accept method in the object structure is
sufficent to serve all of these operations.

Should we create different and separate visitor hierarchies each with
its own accept method but grouping related operations together?

Should we go half way and create these groups but all inherit from a
common visitor base class. This approach also will require a single
accept method.

Currently I am leaning towards the last approach but I am worried that
having a single visitor hierarchy has tied 20 operations together (some
related while others unrelated). The hierarchy is more bushy and deeper
but it still

Whats the general feeling of the developer community on this topic?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Bob Hairgrove
Guest





PostPosted: Thu Dec 29, 2005 3:26 pm    Post subject: Re: Visitor Pattern Choices Reply with quote



On 29 Dec 2005 07:18:37 -0500, "Merlin" <merlin2769 (AT) hotmail (DOT) com>
wrote:

Quote:
Probably there is no right or wrong answer to this but I thought to ask
to put my mind at rest. Ok lets say you have a object hierarchy (eg.
the Glyph in Lexi from GOF book) and you want to use the visitor
pattern. So we place an accept method in the the base class glyph and
procede to create the visitor hierarchy. The accept signature will look
like this

void Glyph::Accept(Visitor& v);

The Visitor hierarchy will have a Vistor base class that will have a
visit method for each different type of Glyph so say if we have an
AssignnentNode and VariableNode there will be two methods

void visit(AssignnentNode& n);
void visit(VariableNode & n);

and in each concrete visitor we implement these methods to behave as we
wish. So far so good...

Imagine you think of 20 different types of operations that you like to
perform on your object structure and u like to use the Visitor pattern
to do this. So you create 20 different classes each implementing the
visitor interface.

Should we inherit all these 20 classes from our visitor base class? If
so this means a single Accept method in the object structure is
sufficent to serve all of these operations.

Should we create different and separate visitor hierarchies each with
its own accept method but grouping related operations together?

Should we go half way and create these groups but all inherit from a
common visitor base class. This approach also will require a single
accept method.

Currently I am leaning towards the last approach but I am worried that
having a single visitor hierarchy has tied 20 operations together (some
related while others unrelated). The hierarchy is more bushy and deeper
but it still

Whats the general feeling of the developer community on this topic?

You should get Andrei Alexandrescu's book "Modern C++ Design". He
devotes an entire chapter to the Visitor design pattern, as well as
many others. In it, he asks (and answers) all the questions you have
posed.

--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Merlin
Guest





PostPosted: Fri Dec 30, 2005 1:06 am    Post subject: Re: Visitor Pattern Choices Reply with quote



Any chance of your insight on this topic. I have read zillion articles
on the visitor pattern and none say anything concrete on this issue. I
can see the advantages of a single Accept method but I dont like the
resultant Visitor hierarchy as we keep adding more and more concrete
visitors.

If we opt for the multiple accept method then we must modify our object
struture when a new family of operations is to be added. I dont like
this either (defeats the purpose of the visitor).

Your comments will be recieved will great interest...

Regards


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze
Guest





PostPosted: Sat Dec 31, 2005 1:39 pm    Post subject: Re: Visitor Pattern Choices Reply with quote

Merlin wrote:

Quote:
Probably there is no right or wrong answer to this

I think that that's the case.

Quote:
but I thought to ask to put my mind at rest. Ok lets say you
have a object hierarchy (eg. the Glyph in Lexi from GOF book)
and you want to use the visitor pattern. So we place an
accept method in the the base class glyph and procede to
create the visitor hierarchy. The accept signature will look
like this

void Glyph::Accept(Visitor& v);

The Visitor hierarchy will have a Vistor base class that will
have a visit method for each different type of Glyph so say if
we have an AssignnentNode and VariableNode there will be two
methods

void visit(AssignnentNode& n);
void visit(VariableNode & n);

and in each concrete visitor we implement these methods to
behave as we wish. So far so good...

Imagine you think of 20 different types of operations that you
like to perform on your object structure and u like to use the
Visitor pattern to do this. So you create 20 different classes
each implementing the visitor interface.

Should we inherit all these 20 classes from our visitor base
class? If so this means a single Accept method in the object
structure is sufficent to serve all of these operations.

Should we create different and separate visitor hierarchies
each with its own accept method but grouping related
operations together?

Should we go half way and create these groups but all inherit
from a common visitor base class. This approach also will
require a single accept method.

Currently I am leaning towards the last approach but I am
worried that having a single visitor hierarchy has tied 20
operations together (some related while others unrelated). The
hierarchy is more bushy and deeper but it still

Whats the general feeling of the developer community on this
topic?

That it really depends on the application. Most of the time,
I'll go with a single visitor base class, with a single accept
function, but it's not a universal best solution; it just
happens to seem to be the most appropriate solution most of the
time for the specific cases I've encountered.

Note that in some cases, treating the nodes as a discriminate
union, rather than using specific callbacks, might also be
appropriate. I tend to do this, for example, if I'm visiting
nodes in a tree, and the visitor may reform the tree based on
the types of child nodes. (A typical example might be
implementing constant folding in a compiler.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Bob Hairgrove
Guest





PostPosted: Sat Dec 31, 2005 1:46 pm    Post subject: Re: Visitor Pattern Choices Reply with quote

On 29 Dec 2005 20:06:33 -0500, "Merlin" <merlin2769 (AT) hotmail (DOT) com>
wrote:

Quote:
Any chance of your insight on this topic.

My insight is limited to the fact that when I have to implement
Visitor, I go to that book and do it his way. From what I have learned
there, it's not a trivial decision, and there are trade-offs in each
direction. But read it yourself and I think you will be glad you did,
even if you end up doing things a little differently than the book
does.

I really don't want to repeat everything Andrei says in this book. But
maybe others will have more hands-on experience.

--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Dave Harris
Guest





PostPosted: Sun Jan 01, 2006 11:26 am    Post subject: Re: Visitor Pattern Choices Reply with quote

[email]merlin2769 (AT) hotmail (DOT) com[/email] (Merlin) wrote (abridged):
Quote:
Should we inherit all these 20 classes from our visitor base class? If
so this means a single Accept method in the object structure is
sufficent to serve all of these operations.

Should we create different and separate visitor hierarchies each with
its own accept method but grouping related operations together?

I wouldn't use that second approach unless there was some advantage. I am
not sure what advantage you see that makes you think it might be the usual
approach.

To be specific, I'd do this if I couldn't find a single interface that all
the visitors could use. For example, the visit method needs to take
arguments or return results. This is rare, though.


Quote:
Should we go half way and create these groups but all inherit from a
common visitor base class. This approach also will require a single
accept method.

This is just the first approach, but using inheritance where appropriate
for reuse and abstraction. I'd use it when appropriate.


Quote:
Currently I am leaning towards the last approach but I am worried that
having a single visitor hierarchy has tied 20 operations together (some
related while others unrelated).

In what way are they tied together? Do you mean that if you change one
visitor subclass, a sibling subclass must change too? How so?

They are already dependant on the Node classes and I see the NodeVisitor
as conceptually being part of the Node interface.

-- Dave Harris, Nottingham, UK.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Merlin
Guest





PostPosted: Mon Jan 02, 2006 11:47 am    Post subject: Re: Visitor Pattern Choices Reply with quote

Thank you for your replies...

I think the general consensus is to use a single Accept method and not
to worry about a Visitor hierarchy that aquires more and more
subclasses.
My first intuition that creating large class hierarchies is a bad thing
does not apply here.

However, I have noted that using the visitor means you tie together the
nodes in the object structure within the visitor classes.
If each class managed its own operation (without visitor) that node
would be more
reusable by itself. When the visitor is used u need to drag all the
nodes together.

Appreciate for taking time to reply...

Regards


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ulrich Eckhardt
Guest





PostPosted: Tue Jan 03, 2006 2:52 pm    Post subject: Re: Visitor Pattern Choices Reply with quote

Merlin wrote:
Quote:
Any chance of your insight on this topic. I have read zillion articles
on the visitor pattern and none say anything concrete on this issue. I
can see the advantages of a single Accept method but I dont like the
resultant Visitor hierarchy as we keep adding more and more concrete
visitors.

If we opt for the multiple accept method then we must modify our object
struture when a new family of operations is to be added. I dont like
this either (defeats the purpose of the visitor).

The purpose of the visitor (in my eyes) is to add virtual function-likes
outside the class. IOW, one concrete type of visitor can replace one
virtual function. The main purpose is to decouple the operations that can
be done with the objects from the objects themselves, thus providing
extensibility. In some cases, this removes most behaviour from these
objects, they only remain shells that encapsulate data.

For that matter, the visitor baseclass is somehow like the void* given to a
callback, it is a 'fits all' solution. Indeed, I often make the visitor
baseclass a nested class of the objects it visits (it is deeply coupled
with it anyway) and I derive all concrete classes from it, no separate
visitor baseclasses.
What I was sometimes tempted to do (but never enough to really do it) was to
create two separate visitors for visiting constant and non-constant
objects.

Quote:
I have read zillion articles on the visitor pattern and none
say anything concrete on this issue.

Hmm, maybe it's time to try it out and then write one? ;^)

Uli


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Merlin
Guest





PostPosted: Wed Jan 04, 2006 2:23 pm    Post subject: Re: Visitor Pattern Choices Reply with quote

Hi Ulrich

Dont't get me wrong I have used the visitor many times but never in
professional capacity with other design patterns. I am gonna
use it in anger soon. I like the idea you put forward for const and
nonconst versions of the visitor. For example when a visitor is applied
to a node
should it modify the node itself or create a new one as it applies the
operation? This is where we may end up having multiple
Accept methods in the visitable hierarchy(node hierarchy).

To be honest with you I dont understand how you can make the base class
a nested class. Surely the base class is the main class and classes
that derive from it are the nested classes. Maybe that is what you
mean. Also you could place the whole visitable hierarchy in a single
class with the concrete visitable classes being the nested classes. I
dont see any advantages to doing such a thing. Infact it makes the code
more difficult to read and understand. Maybe I have misunderstood...
please tell me if that is the case...

Regards

Merlin


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Max Polk
Guest





PostPosted: Wed Jan 04, 2006 6:00 pm    Post subject: Re: Visitor Pattern Choices Reply with quote

Merlin wrote:
Quote:
However, I have noted that using the visitor means you tie together the
nodes in the object structure within the visitor classes.
If each class managed its own operation (without visitor) that node
would be more
reusable by itself. When the visitor is used u need to drag all the
nodes together.

Right, the tradeoff is making it harder for the Visitor so that it is easier
for the classes in your object structure.

You endure the pain of "dragging all the nodes together" within the Visitor
and subclasses for the benefit of being able to add additional Visitor
subclasses without any modification whatsoever to the classes of objects being
visited.

If you dismiss the benefit, you will not understand why you endure the pain.

By the way, the design pattern seems to be missing a name for the objects in
an object structure! Examples in the GoF include "Node", "Element", and
repeated references to "object structure" meaning the single entry point of
the visit. Should I say "Visitee?"

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ulrich Eckhardt
Guest





PostPosted: Wed Jan 04, 2006 7:32 pm    Post subject: Re: Visitor Pattern Choices Reply with quote

Merlin wrote:
Quote:
Dont't get me wrong I have used the visitor many times but never in
professional capacity with other design patterns. I am gonna
use it in anger soon. I like the idea you put forward for const and
nonconst versions of the visitor. For example when a visitor is applied
to a node
should it modify the node itself or create a new one as it applies the
operation? This is where we may end up having multiple
Accept methods in the visitable hierarchy(node hierarchy).

I see a small difference between different operations and const/non-const.
The const/non-const part can be checked and enforced by the compiler, the
rest can't. Therefore, the rest relies on the programmer being honest about
it, the implementations of derived::accept() is still the same. In that
sense, I treat this just as a uniform way to do double-dispatch and the
operation that is performed is hopefully made clear by the
naming/documentation of the visitor.

Thinking more about it, I could well imagine having different accept methods
for e.g. optionally handling the visit as transaction, i.e. one that can be
rolled back under some circumstances. I could as well imagine the visitor
itself handling that without the visited objects being aware of it.

I think this is one of the things where a book can illustrate possibilities
and give hints, but you have to decide yourself which way 'feels' best.


Quote:
To be honest with you I dont understand how you can make the base class
a nested class. Surely the base class is the main class and classes
that derive from it are the nested classes. Maybe that is what you
mean. Also you could place the whole visitable hierarchy in a single
class with the concrete visitable classes being the nested classes. I
dont see any advantages to doing such a thing. Infact it makes the code
more difficult to read and understand. Maybe I have misunderstood...
please tell me if that is the case...

// declare derived classes
struct derived_1;
....
struct derived_n;

// define baseclass
struct base
{
// define baseclass for visitors
struct visitor
{
virtual void visit( derived_1&);
...
virtual void visit( derived_n&);
};
void accept( visitor& v)
{ do_accept(v); }
private:
virtual void do_accept(visitor&) = 0;
};


Uli


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Merlin
Guest





PostPosted: Thu Jan 05, 2006 12:39 pm    Post subject: Re: Visitor Pattern Choices Reply with quote

Quote:
By the way, the design pattern seems to be missing a name for the objects in
an object structure! Examples in the GoF include "Node", "Element", and
repeated references to "object structure" meaning the single entry point of
the visit. Should I say "Visitee?"

Well pointed out!
Modern C++ by Andrei Alexandrescu refers to the two hierarchies in the
following way:
Visitable classes (hierarchy)
Visitor classes (hierarchy)

By the way I am a big fan of the visitor pattern and double
dispatching. Soon I am hoping to look more closely at multiple dispatch
and ways to implement it in C++.

Regards

Merlin


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Merlin
Guest





PostPosted: Thu Jan 05, 2006 12:40 pm    Post subject: Re: Visitor Pattern Choices Reply with quote

Hi Uli

Thanks for the reply.

Now I understand what you mean. You make the visitor base a nested
class within the visitable base class. Where do you put the concrete
visitors?
Personally I dont see any advantages to arranging code like this
because for one thing you cant use your visitor hierarchy for any other
visitable hierarchies(I know rare) and also the code becomes more
difficult to read and understand. Are there benefits I have missed?

Regards

Merlin


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dave Harris
Guest





PostPosted: Thu Jan 05, 2006 1:36 pm    Post subject: Re: Visitor Pattern Choices Reply with quote

[email]eckhardt (AT) satorlaser (DOT) com[/email] (Ulrich Eckhardt) wrote (abridged):
Quote:
What I was sometimes tempted to do (but never enough to really do it)
was to create two separate visitors for visiting constant and
non-constant objects.

Yes, I nearly gave that example too. And I've nearly done it. What I
actually did was use a single visitor with an is_const() member function
and some const_casts, to sort it out at run-time.

-- Dave Harris, Nottingham, UK.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Merlin
Guest





PostPosted: Fri Jan 06, 2006 9:54 am    Post subject: Re: Visitor Pattern Choices Reply with quote

Hi Dave

Quote:
What I was sometimes tempted to do (but never enough to really do it)
was to create two separate visitors for visiting constant and
non-constant objects.

Yes, I nearly gave that example too. And I've nearly done it. What I
actually did was use a single visitor with an is_const() member function
and some const_casts, to sort it out at run-time.

Please correct me if I am wrong. This is what have understood from the
above comments
When implementing a concrete visitor we know if its an operation that
will or will not modify the objects. As a result we set the m_bIsConst
data member of the visitor base class to the right value on
creating the concrete visitor. We also just have a single non-const
function in the object hierarchy.

When we create a visitor to apply to the object, the visitor knows if
its const and therefore we cast the node passed to the visitor to a
const.
This way we wont be able to modify nodes for operations that were meant
to be constant.

If this is a correct take on what you have said then you will get
runtime errors. I have never seen a runtime error on trying to modify a
const object. The compiler has always caught them for me. I wonder what
error we will get...


Merlin


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.