Re: When and where to use Visitor Pattern?



>>There does seem to be a difference in execution time and
dependendency.
>>The visitor (to me) exhibits the more coupling of the options,
because
>>it forces any usage to be coupled to all visititable types, while "if

>>(instanceof(xyz))" only depends on those explicitly stated......this
>>may or may not be necessary....in general the safest way is to assume

>>that making a decision based on the type/interface of a object is
>>intrinsically linked to all possibilities....visitor enforces
>>this.....the "if (instanceof(xyz))"....doesn't.

>I agree that the standard visitor is strongly coupled. Each visitor
>derivative depends on each derivative of the context class. If new
>derivatives are added, all the visitors must be rebuilt and redeployed

>along with all the context derivatives.

OK, wait though, this may be exactly what you want.......you may
**want** all logic pertaining to subtypes of some superclass to break
if a new subtype is added.

i.e. if the logic behind the model is coupled to logic like 'for all
types of', rather than 'for specifically type a,b,c'

classic visitor enforces the former, if instanceof and (acyclic?) are
of the second sort.

You have removed the dependency yes.....but you have changed the
meaning.....that may or may not be sensible.

>On the other hand, if you use an if/else chain of instanceof, then the

>class(es) that contain that chain must be modified for every new
>derivative of the context.

an this is not enforces, if you *want it to be enforced* then you want
the dependency, the coupling and the recompilation....(I'm assuming we
prefer recompilation to wrong production code).


>On the other hand, the if/else chain has a runtime complexity of O(n),

>whereas the visitor has a runtime complexity of O(1). Granted the
'>n' is small, but the cost can still be high.

I agree


>The acyclic visitor solves the dependency problem of visitor while
>compromising little to its speed. Acyclic Visitor also gives the
>ability to decouple individual visitors from the context derivatives
>in a manner similar to the if/else chain.

>In short, the acyclic visitor combines all the best attributes of each

>approach with the exception that it is nowhere near as easy to
>understand as the if/else chain.

maybe, it is a better form than 'instanceof', I agree, in general I
find a typesafe visitor, to be preferable, I have looked at the acyclic
visitor, but never used it.

>So the trade-off become one of clarity over coupling. I suggest that
>the visitor patterns are well enough known that the clarity issue is
>strongly mitigated. If one sees the name XYZVisitor, one has a big
>clue as to what is going on.

yes, but you may want the explicit coupling.

>In the end there is a place for all three approaches. if/else chains
>are best used when the number of derivatives are very small, the
>number of repeated chains are very small, and the hierarchy is not
>likely to grow. Visitor is best used when the number of derivatives
>is not likely to grow, but the number of visitors is. And acyclic
>visitor is best used when both the number of derivatives and the
>number of visitors are likely to grow.

At the cost of the loss of 'for all subtypes'

>>To me the omision of a dependency that does exist is as bad (if not
>>worse) that the inclusion of one that doesn't. i.e. if coupling is
>>inherent it should exist in the code.

>I don't follow this. It is not possible to omit a dependency that
>actually exists.

Lets say we intend to enumerate all the concrete subtypes of a
supertype.

If we use 'instanceof', it is possible to add a subtype and yet the
code that enumerates subtypes, is now wrong......

this is because you have not explicitly encoded the constraint.

A classic visitor would do this, the enumeration code would no longer
compile because it would be missing a visit method.


>It *is* possible to move dependencies to less
>vulnerable parts of the code.

yet not invert them :-)...lets not go there.

> The three variations that we are
>talking about are simply different configurations of the existing
>dependencies.

no......a classic visitor enforces that all code that uses the IVisitor
interface must explicitly handle each named subtype of that interface.

The coupling is a pain, but sometimes it's inherently a pain, removing
it, risks breaking existing code.

P.S.

the cycle is another issue, but there are more than one way to skin
that cat.

.



Relevant Pages

  • Re: When and where to use Visitor Pattern?
    ... along with all the context derivatives. ... On the other hand, if you use an if/else chain of instanceof, then the ... The acyclic visitor solves the dependency problem of visitor while ...
    (comp.object)
  • Re: Opinions on the Law Of Demeter
    ... Now the Contact class has a dependency to know that it's ... Increasing coupling and complexity (which is arguably where LoD-driven ... I want to see some code, not ramblings, Universe. ...
    (comp.object)
  • Re: [patch] Real-Time Preemption, -RT-2.6.10-rc1-mm2-V0.7.1
    ... >>to hold spinlocks in the mutexes as the dependency tree is atomically ... >>unpredictable order of mutexes traversed. ... If the dependency chain is ... As an implementation note, single-owner hard spinlocks seem ...
    (Linux-Kernel)
  • [RFC/PATCH PATCH 3/6] lockdep: Annotate Read/write states
    ... Currently we do not save the recursive read dependencies in the dependency ... since we never have the chain 1 in our dependency list. ... This helps us to define the conflicting states for each lock with ease: ... * Allow read-after-read recursion of the same ...
    (Linux-Kernel)
  • Re: [patch] Real-Time Preemption, -RT-2.6.10-rc1-mm2-V0.7.1
    ... >>the hardirq threads, ... solution is to hold spinlocks in the mutexes as the dependency ... traversal of the chain where contention within the chain under ... send the line "unsubscribe linux-kernel" in ...
    (Linux-Kernel)