Observer vs visitor

So I’ve been reading this article ( http://devzone.zend.com/node/view/id/9) and was
wondering some things about the visitor pattern and also what the precise differences
are between the observer and the visitor.

I know there’s a difference and I’m pretty sure I understand both patterns(at least the observer, because it’s simple).

But it would be nice to have a sort of “formal” summary of the differences.

I’ll list my thoughts about each and you can tell me what’s right and wrong:

Visitor:

  • is “injected” into an object and can be used as a means of providing the target with an implementation
  • target probably only needs to know one method name of the visitor(visit())
  • internally, visitors are able to use the complete public interface of their targets

Observer:

  • good for one-to-many relationships between objects
  • has a less intimate relationship with its “target”(the observed)
  • doesn’t provide an implementation for the target but just reacts to events

Do these sound OK? Is there anything you would add or subtract to each?

A few more questions:

When you implement a visitor, are you also necessarily implementing a strategy pattern? Since each individual
visitor could be seen as a “strategy” in and of itself.

What about plugins(not the Fowler definition)? The visitor seems tailor made for plugins. (and maybe even the observer to a lesser extent)

Do you have or know of any examples of the visitor pattern that doesn’t involve a composite structure?

If you know other languages, this description might help you (it is the clearest for me at least):

Visitor lets you dispatch on two arguments instead of one. You define a different method for different types of the first argument (the implicit self/this), AND for the second argument (the first if you dont count the implicit self/this). In the article’s example: it lets you choose a different method for each node type, and for each list type. You could think of a Visitor as a strategy which is chosen based on the type of the thing you use.

Observer is a simply a lambda which you call to notify something. A little like aspect oriented programming. Or in OOP terms, an observer is something you notify if you do something. If you do A, you say to the observer: “I’m doing A now”, so he can do things you don’t want to worry about.

But if you don’t know what multiple dispatch is, or what a lambda is, this will probably be less clear than the description you gave.

I don’t know what you mean by plugins, can you give an example?

I don’t know what multiple dispatch is(but I’ll read about it) and I thought a lambda was just an anonymous function?

I don’t know what you mean by plugins, can you give an example?
Well, I wasn’t really sure what I meant. I’ve been rolling around ideas in my head for implementing a plugin
api in an app that uses a simple little mvc-like framework somewhat similar to mojavi(most of your app code gets executed inside an “Action”). So I was thinking
each “Action” would trigger certain events and would call the event handler of each plugin that
has registered with that particular action.
But now that I’ve actually typed out some code(it’s still just a fuzzy idea) I see what I was thinking is probably more observer than visitor or maybe a weird visitor/observer hybrid(or maybe neither :eek: ).


  
  <?php
  
  class Plugin {
  
  	function handleEvent($eventName, $data) {
  		$method = "handle_".$eventName;
  		if (method_exists($this, $method)) {
  			$this->$method($data);
  		}
  	}
  
  	// abstract
  	function handle_inserting_foo($data); 
  	// abstract
  	function handle_something_else($data);
  
  	// ...
  }
  
  
  class PluginName extends Plugin {  
  
  	// blah blah
  
  }
  
  
  
  $pluginEnabled = new IAmPluginEnabled;
  $pluginEnabled->attachPlugin(new Plugin1);
  $pluginEnabled->attachPlugin(new Plugin2);
  $pluginEnabled->attachPlugin(new Plugin3);
  $pluginEnabled->execute(...params...);
  
  class IAmPluginEnabled {
  
    // ...
  
  
    function execute(...params...)
    {
  	  $foo = $input->getFoo();
  
  	  // still not sure of the details on how to pass data around
  	  // but I reckon the "event handlers" for this event will modify $foo directly
  	  $this->_notifyPlugins('inserting_foo', $foo);
  
  	  $datalayer->insert($foo);
  
  
  	  // ...
  
    }
  
    // ...
  
    // this method would probably actually be in a parent class
    function _notifyPlugins($eventName, $data)
    {
  	  foreach ($this->_plugins as $plugin)
  	  {   
  		  $pluginName = $plugin->getName();
  		  $output = $plugin->handleEvent($eventName, $data);
  		  $this->_plugins[$pluginName][$eventName]['output'][] = $output;
  	  }
    }
  
    // ...
  
    function attachPlugin($plugin)
    {
  	  $this->_plugins[] = $plugin;
    }
  
  }
  
  ?>
  

I’m finding dear Fenrir quite unintelligible as well. Perhaps he’s just inventing his own vocabulary.

I’ve been rolling around ideas in my head for implementing a plugin
api in an app that uses a simple little mvc-like framework somewhat similar to mojavi(most of your app code gets executed inside an “Action”). So I was thinking
each “Action” would trigger certain events and would call the event handler of each plugin that
has registered with that particular action.
That would definitely be Observer. I don’t know if you saw this thread, but do take a look as I posted a solution of mine there: Creating dynamic plugins for PHP classes

Visitor is meant for extending the functionality of a set of classes, typically forming a Composite hierarchy, in runtime. A good example - one that our good Doctor loves to throw around a lot - is rendering a tree of components for display. The components themselves needn’t know how they should be rendered - you can instead take a Visitor that does know, and have it render the tree. Thus you can get different results by swapping the Visitor instead of touching the code in the components.

Observer is just that - a way to notify interested parties of changes in an object. These two patterns are really quite different, and although I find Visitor can be quite elusive in its finer points, it still shouldn’t by any means get mixed up with Observer.

I hope this provided some enlightenment.

While multiple dispatch is not mumbo jumbo made up by Fernir2, I personally do find his explanation of how it relates to the Visitor pattern (and even more so to PHP) quite ambigious. I could, though, be misunderstanding the concept completely. Could you expand on your description further?

So visitors are only really used when a set of classes are interacting with each other in some way, such as the composite example in the article?

Observer is just that - a way to notify interested parties of changes in an object. These two patterns are really quite different, and although I find Visitor can be quite elusive in its finer points, it still shouldn’t by any means get mixed up with Observer.

I hope this provided some enlightenment.
It may be the fact that they both use association and callbacks that made me think of them as being
similar. But I think I better understand the difference now. I think I’ll just make a rule that
I won’t consider the visitor anymore until I have a composite to work with. :slight_smile:

Edit:

Oops, I meant to comment about your plugin classes. They look nice, although I could create a thread entirely dedicated to asking you questions about it. :slight_smile:

Do you care how we use it?

The typical visitor is transient. It is typically used to traverse a hierarchy of heterogenous objects, defining operations on the objects within the visitor. After the traversal the visitor is typically discarded. After the traversal there is no longer a relationship between the visitor and the visited objects.

The observer subscribes to “events” from another instance (or a number of other instances). It’s a durable relationship where the “publishers” hold a reference to the “observer” (subscriber). The observer don’t define operations as much as “reactions” (i.e. event handlers).

without design plans i can’t advise you squidelydoo, see, i am not aware of your context, so therefore i am not aware of what problem you like to solve and whether these patterns can help you.

Be very carefull with patterns, once you know then you will choke in them cause theire oh so oh so handy (at the end youl end up programming producual stuff cause your out of time)

btw, plug-in = observer, observer::register, observer::dispose, observer::update, and attach an interface please

class Plugin implements iPlugin{} :blush:

I think this google tech talk on list describes multiple dispatch ([URL=http://en.wikipedia.org/wiki/Double_dispatch]double dispatch) and the [URL=http://en.wikipedia.org/wiki/Visitor_pattern]visitor pattern.

That’s a good talk, but unfortunately it’s about Lisp ((which ((is) really)) scary).

I’ll try to explain double/multiple dispatch, but as always, we should start with something you know already: single dispatch.

You have two classes, A and B, and they both have a method called foo:


class A
  def foo
    print "foo in A"
  end
end

class B
  def foo
    print "foo in B"
  end
end

Now if we do:


a = new A
b = new B

a.foo()
b.foo()

You’ll get:


foo in A
foo in B

The computer “knows” that he should execute ‘print “foo in A”’ if we call a.foo(), and ‘print “foo in B”’ if we execute b.foo(). That’s basic, ok?

Now we change the syntax a bit:


class A
class B

def foo(A obj)
  print "foo in A"
end

def foo(B obj)
  print "foo in B"
end

a = new A
b = new B

foo(a)
foo(b)

First we define that there are two classes: A and B. Then we defined 2 methods: foo(A obj) and foo(B obj). foo(A obj) means that we are defining a function named foo, which takes a parameter obj of type A. So this function will be called if we pass in an object of class A. Same for B. Now we create an A and a B in the variables A and B. Then we call foo(a) and foo(b). The computer knows that we mean ‘print “foo in A”’ if we call foo(a) because the class of a is A. Still clear?

Remember that only the syntax has changed. You may feel different about this code: the method foo(A obj) doesn’t belong to class A, does it?

But what if we use methods with multiple parameters?


class A
class B

def foo(A obj1, B obj2)
  print "got an A in obj1 and a B in obj 2"
end

def foo(A obj1, A obj2)
  print "got two A's"
end

a1 = new A
a2 = new A
b1 = new B

foo(a1, b1)
foo(a1, a2)

What will this code do? For the first call: foo(a1, b1), your computer will find the corresponding method definition ‘print “got an A in obj1 and a B in obj 2”’. The second call: foo(a1, a2) will print “got two A’s”. Nothing strange about it, the computer just checks two parameters now. What if we call foo(b1, a1)? That will produce a MethodNotDefinedError or something, because there is no corresponding method foo(B obj1, A obj2).

This is called double dispatch.

What does this have to do with visitor?

Let’s look at Zend’s example:


class Binary extends MyListComponent {

    //...

    function accept(MyListVisitor $visitor) {
        $visitor->visitBinary($this);
    }
}

class WebText extends MyListComposite {

    //...

    function accept(MyListVisitor $visitor) {
        $visitor->visitWebText($this);
        //...
    }
}

//...

class SimpleSearchVisitor extends MyListVisitor {

   //...

    function visitBinary(Binary $comp, $level) {
        // don't match binaries
    }


    function visitWebText(WebText $comp, $level) {
        if ($this->testText($comp->getTitle()) || $this->testText($comp->getText())) {
            $this->matches[] = $comp;
        }
    }
}

What happens here?

The classes Binary and Note “tell” the visitor which class they have: a Binary calls $visitor->visitBinary(), and a WebText calls visitWebText. They call methods based on their class, they dispatch based on their class. We want that because they way you search is different for different types of objects. You want to search the text of WebTexts, but you don’t want to search Binaries.

Let’s translate that to our plain-old-function-language:


class Binary extends MyListComponent
class WebText extends MyListComponent
class SimpleSearchVisitor extends MyListVisitor

def accept(Binary binary, MyListVisitor visitor)
  visitbinary(visitor, binary) # the visitor visits the binary
end

def accept(WebText webtext, MyListVisitor visitor)
  visitwebtext(visitor, webtext)
end

def visitbinary(SimpleSearchVisitor searcher, Binary comp)
  # don't match binaries
end

def visitwebtext(SimpleSearchVisitor searcher, WebText comp)
  if(testtext(searcher, gettitle(comp)) || testtext(searcher, gettext(comp)))
    searcher.matches[] = comp
  end
end

Not very clear…yet. But it should work: we call visitwebtext if we have a webtext, and we call visitbinary if we have a binary. The accept method looks very similar, we can create a single accept method for both types:


class Binary extends MyListComponent
class WebText extends MyListComponent
class SimpleSearchVisitor extends MyListVisitor

def accept(Object node, MyListVisitor visitor)
  visit(visitor, node)
end

def visit(SimpleSearchVisitor searcher, Binary comp)
  # don't match binaries
end

def visit(SimpleSearchVisitor searcher, WebText comp)
  if(testtext(searcher, gettitle(comp)) || testtext(searcher, gettext(comp)))
    searcher.matches[] = comp
  end
end

Now we have one visit method and one accept method. The visit method takes care of the different types, so accept doesn’t have to anymore. The accept method doesn’t do much anymore, so we can remove it.

If we give the methods meaningful names we get this:


class Binary extends MyListComponent
class WebText extends MyListComponent
class SimpleSearcher extends MyListSearcher

def searchwith(SimpleSearcher searcher, Binary comp)
  # don't match binaries
end

def searchwith(SimpleSearcher searcher, WebText comp)
  if(testtext(searcher, gettitle(comp)) || testtext(searcher, gettext(comp)))
    searcher.matches[] = comp
  end
end

So we can now do:


searchmethod = new SimpleSearcher("The Search Query")
thingtosearch = new WebText("The Title", "The Text")

searchwith(searchmethod, thingtosearch) # read: search the WebText with SimpleSearcher

I think this is much simpler than the visitor pattern: we just define a method which dispatches on the searchmethod: the way we search the thing: SimpleSearch, AdvancedSearch, etc. and the thingtosearch: if we’re searching a Binary with SimpleSearch, we don’t want to do anything, if we’re searching a WebText with SimpleSearch, we want to search the title and the text.

I hope this makes sense…

Umm…

Not as creditable from my perspective though, sorry. Also, what’s with making a posting with Ruby huh? This is the PHP forum after all :stuck_out_tongue:

overloading ?

So after reading the c++ example here([url=“http://en.wikipedia.org/wiki/Multimethods”]there’s also one here), my impression is that double/multiple(are they synonymous?) dispatch is mainly just a way to get around methods being
statically overloaded?

  This is probably much less useful in a dynamically typed language as opposed to a statically typed one,  isn't it?(unless you're using PHP5 type hinting, and I'm even sure about that since I'm not using PHP5 yet)

The problem given in that c++ example just doesn't occur in a dynamically typed language as far as I know.
Edit:

On second thought I guess you could equate the need to choose an object at runtime(as with in the visitor/composite article) with the ‘statically overloaded method’ problem. I guess the two
problems really are pretty similar.

I agree - mine neither. “I think this is much simpler than the visitor pattern” - huh? That is the visitor pattern as far as I can see.

Also, what’s with making a posting with Ruby huh? This is the PHP forum after all :stuck_out_tongue:
Well, Ruby syntax slightly modified according to your purposes is absolutely terrific for pseudo, and that’s what his example was.

I do understand that the accept-visitX-construction emulates double dispatch in the way that different handlers are called according to the visited object’s type, but I’m not exactly clear on whether or not Fenrir is trying to make a further point here.

I agree - mine neither. “I think this is much simpler than the visitor pattern” - huh? That is the visitor pattern as far as I can see.

I meant that I find the my last code easier to understand than the first code (Zend’s).

Also, what’s with making a posting with Ruby huh? This is the PHP forum after all

It’s not Ruby, I’ve changed a few things like new A instead of A.new. It is close to Ruby, but it was meant as an easy to read pseudo language.

I do understand that the accept-visitX-construction emulates double dispatch in the way that different handlers are called according to the visited object’s type, but I’m not exactly clear on whether or not Fenrir is trying to make a further point here.

No, I just find it easier to understand in the double dispatch form, so I thought others might find that as well. It’s a higher level view of the concept. If there were any design pattern books for a really low level language, the loop-pattern would be in it:

a = 0
label :start
do_something()
a++
goto :start if a < 10

But PHP programmers have a clearer view of this pattern because it is explicit in their language:

for($a = 0; $a < 10; $a++){
   do_something();
}

or even:


10.times{ do_something() }

You forget about the details (goto :start, counter variable $a), and thus it is easier (for most people) to understand the essence of the pattern.

I thought that the same would apply to visitor/multiple dispatch (apparently not).

overloading ?

No, It looks like overloading, but it is different. Overloading is static, and can happen at compile time. Multiple dispatch has to happen at runtime, because you can’t tell what an object’s class will be.

The same applies to single dispatch:


class Base {
  function foo() {
    echo "Base";
  }
}

class A extends Base {
  function foo() {
    echo "A";
  }
}

class B extends Base {
  function foo() {
    echo "B";
  }
}

Base $o; // type declaration

if($_GET['bar']) {
  $o = new A;
} else {
  $o = new B;
}

$o->foo();

If the polymorphism/overloading happens at compile time, the compiler would see the type declaration Base $o, so it uses the method in Base: echo “Base”; But if if it happens at runtime, the interpreter will just use the method of the class of $o (A or B, not Base).

This is exactly the case :slight_smile: