Category Pattern, a variation of Visitor Pattern:
Documented in Pattern Languages Of Program Design volume three (1997), chapter 7.
Available online as www.objectmentor.com
It is discussed and developed in Modern Cee Plus Plus Design chapter 10.
"The Acyclic Visitor pattern allows new functions to be added to existing class hierarchies without affecting those hierarchies, and without creating the dependency cycles that are inherent to the Gang Of Four Visitor Pattern."
[...quoted with light editing.]
----__ Acyclic Visitor:
The receiver of the Visitor dynamic_casts the Visitor to determine if it is the type of Visitor it will accept, and if so, passes itself to the Visitor.
How is this better than:
An operation or class that will only operate on a specific subtype dynamic_casts the instance to determine if it is of that subtype.
The Visitor pattern has two purposes:
1) Enumeration -> as target of an iteration through a collection of a known set of subtypes
2) Type Determination (Capability Query) -> determine which subtype we are currently examining.
If there is no need for an enumeration target, and a dynamic_cast is acceptable for the Capability Query, there is no need for the Visitor Pattern.
Does anybody want to comment on this observation? Does it make sense?
I developed Acyclic Visitor independently in designing class frameworks. (John Vlissides also developed a variation in Visitor In Frameworks.)
In a particular User Interface framework, a state machine (State Pattern) controlled the software's progress through a dialogue with the user. When the user acts, this can cause an event (Command Pattern) to be sent to the state machine, causing it to change to the next state in the dialogue. But what events might a state receive? And how might it handle these events? Answer: It depends on the application. But I can't recompile the framework every time someone wants to create a custom event in a new application. That's that nasty cyclic dependency.
So I pushed the issue of event-handling onto the application. For each event class the application defined, it needed a corresponding event receiver class. If a particular state needed to respond to a particular kind of event, the state class would inherit from the appropriate receiver. The event would then Dynamic Cast to the corresponding receiver class, executing the event if the cast was successful.
In another instance, I was creating a diagnostic framework. Diagnostic tests inherited from a test base class (Strategy Pattern). Each class of test would generate test-specific status, which could be relayed to the user. But the application needs to be able to use application-specific test classes, with application-specific status classes. And the diagnostic framework needs to be completely decoupled from the UI, which may even have its own completely separate framework.
So for each status class, there is a corresponding status receiver class. Each status class knows what kind of receiver can grok it, and Dynamic Casts to it. One status message, one Dynamic Cast. At least it's better than a list of twenty Dynamic Casts in a gigantic if-then-elseif, as the UI code hunts around for a kind of status it knows about.
--Tim King
I recently refactored my way into a situation identical to that Tim describes (quite a testament to the magic of refactoring): State + Command compelled Visitor, and then I had a peloton of cycles to get rid of.
It turns out that Acyclic Visitor as written, translated into Java Language, still has a cycle between each element- Visitor pair. Element subclasses (commands) refer to each Visitor subclass (state) via an interface; each Visitor interface must refer to an element subclass, and we have a cycle. The cycle doesn't affect the framework, but I don't like to tolerate even little local ones.The cycle can be easily removed by having Visitors refer to elements via interfaces, but I had a large number of elements, they were quite simple, and the code bloat of having an interface for each element seemed excessive.
Looking for better solutions I came across Uncle Bob's Java version, www.objectmentor.com , which has the same issue, perhaps indicated by the bidirectional arrows in the diagram, although not explicitly discussed. (I believe the issue almost goes away in Cee Plus Plus if the elements and Visitors see each others' declarations but not their definitions, but I haven't worked through it.)
I settled for using reflection, more or less as described in www.javaworld.com . This completely removes any knowledge of the whole business from the elements. The reflective dispatch can be done in one place in a Visitor superclass. The result is quite economical and easy to follow. The only hitch is that because the visit methods are only called via reflection, code checkers think they're unused.
See original on c2.com