By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,117 Members | 2,142 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,117 IT Pros & Developers. It's quick & easy.

the Visitor Design Pattern

P: n/a
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 itself. The called class has special
functions for each class that can call it.

With the visitor pattern, the calling class can have new operations
added without being changed itself.

http://www.fluffycat.com/SDCMSv2/PHP...terns-Visitor/
Nov 29 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a

FluffyCat wrote:
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 itself. The called class has special
functions for each class that can call it.

With the visitor pattern, the calling class can have new operations
added without being changed itself.

http://www.fluffycat.com/SDCMSv2/PHP...terns-Visitor/


A class that passes an instance of itself to another class means you
don't freaking know what you're doing. What's next? The spaghetti
design pattern?

Nov 29 '05 #2

P: n/a
Chung Leong wrote:
FluffyCat wrote:
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 itself. The called class has special
functions for each class that can call it.

With the visitor pattern, the calling class can have new operations
added without being changed itself.

http://www.fluffycat.com/SDCMSv2/PHP...terns-Visitor/


A class that passes an instance of itself to another class means you
don't freaking know what you're doing. What's next? The spaghetti
design pattern?


I think the OP has phrased this badly. He actually has an object
passing this ($this) to a method in another object, which is hardly
uncommon practice in most OO languages (e.g. registering a callback
interface with a child object).

However, the OP's example is not particularly great, as it's all being
driven from outside the objects in question.

--
Oli

Nov 29 '05 #3

P: n/a
I know these patterns can look like spaghetti code at first, but if
you will be doing any serious OO programming they are extremely
important. The visitor pattern is absolutely one that is used and
useful, so it is worth taking the time to understand it.

Sometimes I can describe these patterns well and sometimes not.
Judging from the response this is probably a not. Maybe I should have
said "the current instance of itself" instead, which is what $this is,
instead of "an instance of itself", which could imply a new instance.
Maybe instead of describing these patterns I should just have the UML
and the code. I don't have a tool to create UML for PHP yet, which
defiantely hurts my examples.

I try to make these examples as simple as possible, while sticking to
the original intent of the pattern. In the GoF on page 334 - 335 the
UML shows anObjectStructure calling the concrete element (which I call
the visitee) with accept(Visitor), the concrete element then calls the
visitor, which in turn calls a method back in the concrete element.
So, I've just used my "testVisitor" in place of anObjectStructure. To
me, the anObjectStructure just kicked things off by calling the
concrete element with a visitor, so I gave the simplest representation
I could of it. Do you really think this example doesn't meet the
required intent of the visitor pattern, at least in it's simplest
form?

A useful example of the visitor pattern could show the visitor being
able to create HTML or XML output for the same concrete element. I
didn't do this because it would "muddy the waters" of the example with
whatever overhead I'd need to add to produce the HTML and XML. That
might be a nice second more robust example of the visitor pattern to
do after I complete my simple versions of all the most important
design patterns.

http://www.fluffycat.com/SDCMSv2/PHP...terns-Visitor/

p.s. - even if you weren't exacly crazy about it, thanks very much for
checking out my pattern example and commenting on it!

On 29 Nov 2005 04:43:02 -0800, "Oli Filth" <ca***@olifilth.co.uk>
wrote:
Chung Leong wrote:
FluffyCat wrote:
> 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 itself. The called class has special
> functions for each class that can call it.
>
> With the visitor pattern, the calling class can have new operations
> added without being changed itself.
>
> http://www.fluffycat.com/SDCMSv2/PHP...terns-Visitor/


A class that passes an instance of itself to another class means you
don't freaking know what you're doing. What's next? The spaghetti
design pattern?


I think the OP has phrased this badly. He actually has an object
passing this ($this) to a method in another object, which is hardly
uncommon practice in most OO languages (e.g. registering a callback
interface with a child object).

However, the OP's example is not particularly great, as it's all being
driven from outside the objects in question.

Nov 29 '05 #4

P: n/a
Oli Filth wrote:
I think the OP has phrased this badly. He actually has an object
passing this ($this) to a method in another object, which is hardly
uncommon practice in most OO languages (e.g. registering a callback
interface with a child object).


That's very different from object A calling a method of object B which
in turns invokes methods on object A now isn't it? What the OP
described can be more aptly called the prostitution design pattern.
Object J has a need that it cannot satisfy, so it visits object H to
get its private part operated upon. It's sick. It's immoral. Objects
should only play around with their own thingies.

Nov 30 '05 #5

P: n/a

Sure, I guess you could claim visitor is a euphemism for prostitute.
Keep in mind that these are inherently two consenting objects, and
what they are doing is legal under the laws of PHP 5 and the Zend
Engine. OO-phobe sentiment will only keep you mired in procedural
programming.

On 29 Nov 2005 22:46:39 -0800, "Chung Leong"
<ch***********@hotmail.com> wrote:
Oli Filth wrote:
I think the OP has phrased this badly. He actually has an object
passing this ($this) to a method in another object, which is hardly
uncommon practice in most OO languages (e.g. registering a callback
interface with a child object).


That's very different from object A calling a method of object B which
in turns invokes methods on object A now isn't it? What the OP
described can be more aptly called the prostitution design pattern.
Object J has a need that it cannot satisfy, so it visits object H to
get its private part operated upon. It's sick. It's immoral. Objects
should only play around with their own thingies.

Nov 30 '05 #6

P: n/a

Chung Leong wrote:
Oli Filth wrote:
I think the OP has phrased this badly. He actually has an object
passing this ($this) to a method in another object, which is hardly
uncommon practice in most OO languages (e.g. registering a callback
interface with a child object).
That's very different from object A calling a method of object B which
in turns invokes methods on object A now isn't it? What the OP
described


As I said, it's really not a great example (of something that's a good
idea in principle).

His example, which basically boils down to:

$book = new Book();
$plainVisitor = new PlainDescriptionVisitor();
$book->accept($plainVisitor);
$plainVisitor->getDescription();

has a pointless line $book->accept(), i.e. the Book is "doing" the
work.

$book = new Book();
PlainDescriptionVisitor::describe($book);

would have made much more sense, or if polymorphism of the visitors is
a concern:

$book = new Book();
$plainVisitor = new PlainDescriptionVisitor();
$plainVisitor->visit($book);
....
$plainVisitor->getDescription();

Either way, it avoids the $book->accept() call, which offers no
semantic value.
can be more aptly called the prostitution design pattern.
Object J has a need that it cannot satisfy, so it visits object H to
get its private part operated upon. It's sick. It's immoral. Objects
should only play around with their own thingies.


:)

--
Oli

Nov 30 '05 #7

P: n/a
FluffyCat wrote:
I know these patterns can look like spaghetti code at first, but if
you will be doing any serious OO programming they are extremely
important. The visitor pattern is absolutely one that is used and
useful, so it is worth taking the time to understand it.

I try to make these examples as simple as possible, while sticking to
the original intent of the pattern. In the GoF on page 334 - 335 the
UML shows anObjectStructure calling the concrete element (which I call
the visitee) with accept(Visitor), the concrete element then calls the
visitor, which in turn calls a method back in the concrete element.
Exactly; what's the point in calling Visitee->accept(Visitor), whose
only job is to call Visitor->visit(this)? If ObjectStructure has a
reference to both Visitor and Visitee, why doesn't it just call
Visitor->visit(Visitee)? This would make for a simpler, more intuitive
arrangement.
A useful example of the visitor pattern could show the visitor being
able to create HTML or XML output for the same concrete element. I
didn't do this because it would "muddy the waters" of the example with
whatever overhead I'd need to add to produce the HTML and XML.


But even that wouldn't require the double dispatch, e.g.:

$book = new Book();
$HTMLThing = new HTMLThing();
$XMLThing = new XMLThing();

$HTMLThing->display($book);
$XMLThing->display($book);
P.S.: Please don't top-post...

--
Oli

Nov 30 '05 #8

P: n/a
Oli Filth wrote:

$book = new Book();
PlainDescriptionVisitor::describe($book);


Passing input data to a block of reusable code--that's just normal
programming. What this world coming to when programmers feel they can't
do something if it's not called a design pattern? The end is near, I
fear.

Nov 30 '05 #9

P: n/a
On 30 Nov 2005 08:35:22 -0800, "Oli Filth" <ca***@olifilth.co.uk>
wrote:
FluffyCat wrote:
I know these patterns can look like spaghetti code at first, but if
you will be doing any serious OO programming they are extremely
important. The visitor pattern is absolutely one that is used and
useful, so it is worth taking the time to understand it.

I try to make these examples as simple as possible, while sticking to
the original intent of the pattern. In the GoF on page 334 - 335 the
UML shows anObjectStructure calling the concrete element (which I call
the visitee) with accept(Visitor), the concrete element then calls the
visitor, which in turn calls a method back in the concrete element.
Exactly; what's the point in calling Visitee->accept(Visitor), whose
only job is to call Visitor->visit(this)? If ObjectStructure has a
reference to both Visitor and Visitee, why doesn't it just call
Visitor->visit(Visitee)? This would make for a simpler, more intuitive
arrangement.


I'm not clear if you object to the Visitor pattern as it is generally
accepted in the OO world, or only to my example of it.

The accept mechanism allows the objectStructure (my testVisitor) to
create the Visitee (eg BookVisitee) and Visitor (eg
PlainDescriptionVisitor) that is appropriate for whatever
obectStructure needs. The objectStructure then uses
Visitee->visit(Visitor) to simultaneously register the appropriate
Visitor with the Visitee, and allow the Visitee to call the approprite
function for and with itself in the Visitor. Then the function in the
Visitor having been passed a Visitee knows what functions in the
Visitee it needs.

The objectStructure merely chooses the pieces to be used, the pieces
then in turn run the show. Sure, objectStructure could control
everything and not let the pieces specify anything. In the Visitor
pattern the Structure calls the Visitee calls the Visitor calls the
Visitor. Of course, there are often many useful variations of any
pattern, and a derivative might be just the thing for a given need.
I'm just trying to show the pattern in it's most classical established
form.

(I know my written descriptions of these patterns aren't the greatest.
This is why I merely provide examples and don't have much tutorial
verbiage on www.fluffycat.com/SDCMSv2/)
A useful example of the visitor pattern could show the visitor being
able to create HTML or XML output for the same concrete element. I
didn't do this because it would "muddy the waters" of the example with
whatever overhead I'd need to add to produce the HTML and XML.


But even that wouldn't require the double dispatch, e.g.:

$book = new Book();
$HTMLThing = new HTMLThing();
$XMLThing = new XMLThing();

$HTMLThing->display($book);
$XMLThing->display($book);


Well, I'd have a more robust example in general, which could show the
pattern in a more useful light, but also more complex. I think that
the simplicity of testVisitor could be undermining my example to some
degree by making some things simpler and yet also perhaps pointless.
P.S.: Please don't top-post...


k, while I think "top-posting" can make the response part of the
message clearer, if it is against established comp.lang.php standards
I'll certainly stop. I'm all about following standards.
Nov 30 '05 #10

P: n/a
On 30 Nov 2005 10:57:01 -0800, "Chung Leong"
<ch***********@hotmail.com> wrote:
Oli Filth wrote:

$book = new Book();
PlainDescriptionVisitor::describe($book);


Passing input data to a block of reusable code--that's just normal
programming. What this world coming to when programmers feel they can't
do something if it's not called a design pattern? The end is near, I
fear.

It's hard to say just how much OO will catch on in PHP. If it does,
patterns are certain to follow. If you find yourself working in a
team with pattern fans, your best defense against using patterns is to
understand them so you can defend your reasons for not using them.
Nov 30 '05 #11

P: n/a
FluffyCat said the following on 30/11/2005 19:48:
On 30 Nov 2005 08:35:22 -0800, "Oli Filth" <ca***@olifilth.co.uk>
wrote:

Exactly; what's the point in calling Visitee->accept(Visitor), whose
only job is to call Visitor->visit(this)? If ObjectStructure has a
reference to both Visitor and Visitee, why doesn't it just call
Visitor->visit(Visitee)? This would make for a simpler, more intuitive
arrangement.


I'm not clear if you object to the Visitor pattern as it is generally
accepted in the OO world, or only to my example of it.

I think I'd have to say that I "object" (a rather strong term, though ;)
) to your example, because it doesn't demonstrate any benefits that
arise from the double dispatch.

If you were treating $book and $software polymorphically within
testVisitor.php, then this would be a viable demonstration of the use of
double dispatch.

Alternatively, if your accept() methods were doing more than just
calling the visit() methods (i.e. actually performing some sort of
private operations inside the Visitee classes) then this would also
demonstrate some kind of "point" to an arrangement like this.

But as it stands, in testVisitor.php you're merely substituting a call
to $plainVisitor->visitBook($book) with a call to
$book->accept($plainVisitor), which is only likely to make people think
"Well, what's the point in that?".


--
Oli
Nov 30 '05 #12

P: n/a
Ok, excellent stuff to think about. The problem with doing these
examples is that there is a huge difference between getting your code
to run and having a good example of a pattern.

I did add a function to my testVisitor that will take in any Visitee
and Visitor and call $visitee->accept($visitor), and so adds a bit
more polymorphism to the mix.

I'm still not convinced this is necessary for a viable Visitor
example, but if it helps to make things seem at all clearer I'm
totally into it.

I would have preferred, as was suggested, to give the Visitor some
special access to Visitor. However, I don't see how to do this with
PHP. In C++ you can set up friend (?) classes. In Java you can have
package level access. As is stated in GoF, "the pattern often forces
you to provide public operations to access the element's internal
state, which may compromise it's encapsulation". I guess you could
say that Visitor Pattern is a way to add a new operation to a class
with out altering the class - but without the advantage of having any
special class access.
Dec 1 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.