Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should you really use the visitor pattern

Ok before marking this as a duplicate let me clarify myself. I'm reading about the visitor pattern and its applicable uses.

I've stumbled upon this post: When should I use the Visitor Design Pattern?

and the user who wrote the first answer says as follow :

Now we want to add a new operation to the hierarchy, namely we want each animal to make its sound. As far as the hierarchy is this simple, you can do it with straight polymorphism:
...
But proceeding in this way, each time you want to add an operation you must modify the interface to every single class of the hierarchy.

Now, I mostly see why it's needed from his perspective, it's basically a way to cut compilation time by making it so not every time you want to add a new polymorphic method to a class hierarchy, the whole hierarchy will get recompiled.

But he's also saying that it's fine adding a new polymorphic method to the hierarchy as long as it's a "simple" hierarchy. But my question is when do you set your line and decide on what is simple and what is not.
Also, what if an hierarchy is a complex one, but adding a new method just make total sense to be and instance method rather than having the operation in a complete different class ?

Searching a bit more I found this article explaining the visitor pattern and it's uses http://butunclebob.com/ArticleS.UncleBob.IuseVisitor

The author gave an example where writing an instance method makes the object coupled to something and moving the method to a different class (The visitor) breaks the decoupling. This made more sense to me, but I'm still not quite sure when this pattern should really be used, the first argument of "changing the hierarchy time every time you want to add a new polymorphic method..." seems to me like an excuse because if a method seems to fit in the hierarchy it should be there logically, Assuming the Animal example was a really complex hierarchy and I would have decided to add make sound method, adding an instance method would be a logical choice (in my mind).
But maybe I'm wrong so I'm here asking for more insight about this, maybe someone could enlighten me.

like image 275
JoJo Dmlx Avatar asked Oct 31 '15 21:10

JoJo Dmlx


1 Answers

The Visitor pattern is for composing things. Basically that's when you use the visitor pattern: you have a non trivial operation which needs to compose primitive operation/properties and may need to adapt its behaviour depending on the type of value it works with. You'd put the primitive operations and properties in the class hierarchy itself, and extract the composition of those things into a visitor pattern type operation.

Essentially the visitor pattern is a crutch for languages which lack 'true' polymorphism[1] and higher order functions. Otherwise you'd simply define the composition of operations as a higher order polymorphic function foo() that simply takes helper functions as parameters to resolve the specifics.

So it's a limitation of the language more than a strength of design. If you use this sort of thing a lot to cut down on compilation times, you should consider whether you are trying to work against the tool or with the tool, i.e. whether you are doing the equivalent of a "real programmer who can program Fortran in any language". (And whether it is perhaps time to pick up/learn a different tool, besides the hammer.)

  1. By which I mean the ability of functions to work on values of "arbitrary types" without having to nail down the type to something specific (A or B), meaning the exact type/signature of the function/call changes depending on what you pass in.
like image 147
user268396 Avatar answered Oct 24 '22 16:10

user268396