Daily Patterns #15
-
Upload
oleg-godovykh -
Category
Documents
-
view
215 -
download
0
Transcript of Daily Patterns #15
-
7/31/2019 Daily Patterns #15
1/3
VISITOR DESIGN PATTERN
INTENT
Represent anoperation to be
performed on theelements of an objectstructure. Visitor lets
you define a new
operation withoutchanging the classesof the elements onwhich it operates.
The classic techniquefor recovering losttype information.
Do the right thingbased on the type of
two objects.
Double dispatch
Problem
Many distinct andunrelated
operations need tobe performed onnode objects in aheterogeneous
aggregatestructure. You wantto avoid polluting
the node classeswith these
operations. And, youdont want to have
to query the type ofeach node and castthe pointer to the
correct typebefore performing
the desiredoperation.
Visitorsprimary purpose is to abstract
functionality that can be applied toan aggregate hierarchy of elementobjects. The approach encourages
designing lightweight Element classes- because processing functionality is
removed from their list ofresponsibilities. New functionality
can easily be added to the originalinheritance hierarchy by creating a
new Visitor subclass.
Visitor implementsdouble dispatch. OO messages
routinely manifest singledispatch - the operation that is
executed depends on: the name ofthe request, and the type of the
receiver. In double dispatch, theoperation executed depends on: thename of the request, and the type
of TWO receivers (the type of theVisitor and the type of the
element it visits).
The implementationproceeds as follows. Create a
Visitor class hierarchy that defines apure virtual visit() method in the
abstract base class for each concretederived class in the aggregate node
hierarchy. Each visit() method accepts asingle argument - a pointer or
reference to an original Elementderived class.
Each operation tobe supported is modelled witha concrete derived class of the
Visitor hierarchy. The visit()methods declared in the Visitor
base class are now defined in eachderived subclass by allocating thetype query and cast code in theoriginal implementation to theappropriate overloaded visit()
method.
-
7/31/2019 Daily Patterns #15
2/3
Add a single purevirtual accept() methodto the base class of
the Element hierarchy.accept() is defined to
receive a singleargument - a pointer or
reference to theabstract base class of
the Visitor hierarchy.
Each concrete derivedclass of the Element
hierarchy implements theaccept() method by
simply calling the visit()method on the concretederived instance of the
Visitor hierarchy that itwas passed, passing its
this pointer as the
sole argument.
Everything forelements and visitorsis now set-up. When the
client needs an operationto be performed, (s)he
creates an instance of theVistor object, calls theaccept() method on each
Element object, andpasses the Visitor object.
The accept() methodcauses flow of control
to find the correctElement subclass. Thenwhen the visit() method
is invoked, flow ofcontrol is vectored to
the correct Visitorsubclass. accept()dispatch plus visit()
dispatch equals doubledispatch.
The Visitor patternmakes adding new
operations (or utilities)easy - simply add a newVisitor derived class.
But, if the subclasses inthe aggregate node
hierarchy are not stable,keeping the Visitorsubclasses in sync
requires a prohibitiveamount of effort.
An acknowledgedobjection to the Visitor
pattern is that isrepresents a regression
to functionaldecomposition - separatethe algorithms from the
data structures. Whilethis is a legitimate
interpretation, perhaps abetter perspective/
rationale is the goal ofpromoting non-
traditional behavior tofull object status.
The Element hierarchyis instrumented with auniversal methodadapter. The
implementation ofaccept() in eachElement derived classis always the same. But it cannot be moved tothe Element base classand inherited by allderived classesbecause a reference tothis in the Elementclass always maps tothe base type Element.
When the polymorphicfirstDispatch() method iscalled on an abstract Firstobject, the concrete type ofthat object is recovered.When the polymorphic
secondDispatch() method iscalled on an abstract Secondobject, its concrete type isrecovered. The applicationfunctionality appropriate forthis pair of types can now beexercised.
-
7/31/2019 Daily Patterns #15
3/3
1. Confirm that thecurrent hierarchy(known as the Elementhierarchy) will be fairlystable and that thepublic interface ofthese classes is
sufficient for theaccess the Visitorclasses will require.If these conditions arenot met, then the Visitorpattern is not a goodmatch.
2. Create a Visitor baseclass with avisit(ElementXxx)method for eachElement derived type.
3. Add an accept(Visitor)method to the Elementhierarchy. Theimplementation in eachElement derived classis always the same accept( Visitor v ){ v.visit( this ); }.Because of cyclicdependencies, thedeclaration of the
Element and Visitorclasses will need to beinterleaved.
4. The Element hierarchyis coupled only to theVisitor base class, butthe Visitor hierarchy iscoupled to eachElement derived class.If the stability of theElement hierarchy is
low, and the stability ofthe Visitor hierarchy ishigh; consider swappingthe roles of the twohierarchies.
5. Create a Visitorderived class for eachoperation to beperformed on Elementobjects. visit()implementations willrely on the Elements
public interface.
6. The client createsVisitor objects andpasses each to Elementobjects by callingaccept().
The Visitorpattern represents an
operation to be performed on theelements of an object structure without
changing the classes on which it operates. Thispattern can be observed in the operation of a taxi
company. When a person calls a taxi company(accepting a visitor), the company dispatches a cab
to the customer. Upon entering the taxi the
customer, or Visitor, is no longer incontrol of his or her owntransportation, the taxi
(driver) is.
The abstract syntaxtree of Interpreter is a
Composite (thereforeIterator and Visitor are
also applicable).
Iterator cantraverse a
Composite. Visitor canapply an operation
over a Composite.
The Visitorpattern is like a
more powerfulCommand pattern becausethe visitor may initiatewhatever is appropriatefor the kind of object
it encounters.
The Visitor
pattern is theclassic technique forrecovering lost typeinformation withoutresorting to dynamic
casts.