473,320 Members | 1,724 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Visitor design pattern - breaking dependence on the target hierarchy

Hi everyone.
When using visitor pattern, we have a nasty dependence on the types of
visitable objects that is coded way on top on the visitor hierarchy. i
mean, like this:

class AbstractVisitor
{
public:
virtual void visit(Object_type_1 *);
virtual void visit(Object_type_2 *)
.............................
virtual void visit(Object_type_N *;
};

That is so nice that visitable objects are aware only of the
AbstractVisitor type, but that's not so good that every concrete
visitor must know about the whole multitude of visitable object types!

I've encountered this problem when trying to separate visitor/visitable
classes into libraries. That is, suppose there is a base library Base,
that contains definitions for AbstractVisitor and some AbstractObject
class, which is the base class for all visitable objects. Pointers to
AbstractObject's are stored in some STL container inside the Base
library. Objects can be manipulated by visitors only through some
method in the container class:

// ------ Classes contained in the Base library ------
// Abstract.h
class AbstractVisitor;
class AbstractObject
{
public:
void accept(AbstractVisitor *);
};

// Container.h
#include "AbstractVisitor.h"
#include "AbstractObject.h"

class Container
{
private:
std::set<AbstractObject *> objects_;.
public:
void manipulate(AbstractObject *, AbstractVisitor *);
};

There could be multiple client libraries that have their specific
AbstractObject descendants and visitors, which are run only on the
objects defined in the same library. For instance:

// ------ Classes contained in ClientLibrary1 ------
class ClientObject1
:
public AbstractObject
{
public:
void accept(AbstractVisitor *);
};

class ClientVisitor1
:
public AbstractVisitor
{
public:
// It is desirable that here are contained only methods pertaining to
relevant objects
void visit(ClientObject1 *);
// other visit()'s
};

Naturally, it is not good for ClientLibrary1 to know about object types
contained in some ClientLibrary2, for instance.

The aim can be achieved through the use of dynamic_cast'ing, though. In
order to accomplish, we modify the visitor object hierarchy slightly by
inserting a templatized ancestor class:

// ------ Base library code ------
class AbstractVisitor
{
public:
// AbstractVisitor now knows nothing about the objects
// on which it's descendants operate
virtual void visit(void *); // default method
};

template<class TObjectType>
class InterimVisitor
:
virtual public AbstractVisitor
{
public:
virtual void visit(TObjectType *);
};

The concrete visitor classes can now be defined as follows:

// ------ Client library code
class ConcreteVisitor
:
public InterimVisitor<ObjectType1>,
public InterimVisitor<ObjectType2>
{
public:
virtual void visit(ObjectType1 *);
virtual void visit(ObjectType2 *);
};

And finally, the use of dynamic_cast does the right job in overloaded
accept methods:

class SomeObject
:
public AbstractObject
{
public:
void accept(AbstractVisitor * v)
{
Interim<SomeObject> * i = dynamic_cast<Interim<SomeObject> *>(v);
if (i)
{
// v is allowed to visit this object
v->visit(this);
}
}
};

I'm sorry for including this much of code and statements that you all
probably have seen thousand times :-). And the main question is - are
there any other solutions that do not incur performance penalties
caused by the use of dynamic_cast? Thanks in advance

Mar 7 '06 #1
0 1890

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: George Sakkis | last post by:
I'm looking for a design to a problem I came across, which goes like this (no, it's not homework): 1. There is a (single inheritance) hierarchy of domain classes, say A<-B<-..<-Z (arrows point...
2
by: Wavemaker | last post by:
I've been playing with C# v2.0 today, and having quite a bit of fun. The new version has added iterators. The iterators are coded directly into the class to be iterated. For example: public...
12
by: FluffyCat | last post by:
New on November 28, 2005 for www.FluffyCat.com PHP 5 Design Pattern Examples - the Visitor Pattern. In the Visitor pattern, one class calls a function in another class and passes an instance of...
17
by: Merlin | last post by:
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...
25
by: lovecreatesbeauty | last post by:
Could you talk something about the general rules on the interface (function) design in C program that recognized publically? Or introduce some good advice of yourself. How do you think about...
1
by: RedLars | last post by:
Hi, Given this class definition, public class Node { Node parent; object current; ArrayList children;
1
by: JosAH | last post by:
Greetings, this week we let go of all that algebraic stuff and concentrate a bit more on what object oriented programming is all about. Java claims to support OO, so why not use it? In this...
0
weaknessforcats
by: weaknessforcats | last post by:
Design Patterns: Visitor Introduction Polymorphism requires a class hierarchy where the interface to the hierarchy is in the base class. Virtual functions allow derived classes to override base...
3
by: aaragon | last post by:
Hello everyone, I've been trying to work with the visitor design pattern, and it works fine except for the following. Let's suppose that we have a fixed hierarchy of classes (many of them)...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.