unit 28 visitor
DESCRIPTION
Unit 28 Visitor. Summary prepared by Kirk Scott. Design Patterns in Java Chapter 29 Visitor. Summary prepared by Kirk Scott. The Introduction Before the Introduction. My presentation of the visitor pattern will follow this outline: - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/1.jpg)
1
Unit 28Visitor
Summary prepared by Kirk Scott
![Page 2: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/2.jpg)
2
![Page 3: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/3.jpg)
3
![Page 4: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/4.jpg)
4
![Page 5: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/5.jpg)
5
![Page 6: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/6.jpg)
6
![Page 7: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/7.jpg)
7
![Page 8: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/8.jpg)
8
Design Patterns in JavaChapter 29
Visitor
Summary prepared by Kirk Scott
![Page 9: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/9.jpg)
9
The Introduction Before the Introduction
• My presentation of the visitor pattern will follow this outline:
• The book presents the Visitor design pattern by using it to extend code which is based on the Composite design pattern
• I will follow this example in order to define the pattern
![Page 10: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/10.jpg)
10
• I will then try to illustrate the pattern with an example simpler than the book’s
• In my example the Visitor pattern will be applied to a leaf of a Component only
• I will not give complete code for an implementation of the pattern for a Composite
![Page 11: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/11.jpg)
11
• I will then return to the book’s discussion of an important syntactical point that becomes apparent with this pattern
• I will then examine the potential shortcomings of the pattern
![Page 12: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/12.jpg)
12
• The posted “assignment” for this unit deals with an implementation of the pattern for a Composite even though I don’t pursue that in depth in these overheads
• It should be within your ability to apply the pattern in that context, using the book and these overheads as a guide
• Such a question could appear on the last test
![Page 13: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/13.jpg)
13
Starting the Book Material on the Pattern
• Assuming that you have access to the code for a class, extending the class would mean adding methods to it, for example
• If you, as a client developer, cannot change the code of a given class, the class developer can make it possible for you to add functionality to the class
![Page 14: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/14.jpg)
14
• The developer of the service class defines a visitor interface containing visit() methods
• The developer of the service class defines a an accept() method in the service classes
• The accept() method accepts an instance of a visitor as an explicit parameter
• Inside the accept() method, visit() is called on the service object that accept() was called on
![Page 15: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/15.jpg)
15
• The client developer creates concrete classes that implement the visitor interface
• These classes contain concrete implementations of the visit() method
• It is these concrete visit() methods that the service code accept() method calls on itself
![Page 16: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/16.jpg)
16
• The client code creates a service object, creates a visitor object, and calls accept() on the service object, passing the visitor in
• Note how passing objects that contain desired functionality is reminiscent of the Command design pattern
![Page 17: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/17.jpg)
17
Book Definition of Pattern
• Book definition:• The intent of Visitor is to let you define a new
operation for a hierarchy without changing the hierarchy classes.
![Page 18: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/18.jpg)
18
Visitor Mechanics
• The visitor pattern is based on some standard mechanics
• These mechanics potentially support an unlimited variety of extensions (new methods) that can be applied to service classes by clients
• The needed mechanics fall into three parts:
![Page 19: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/19.jpg)
19
The Visitor Interface
• 1. There is a visitor interface that is associated with the set of service classes
• This visitor interface is defined to have one or more methods named visit()
• There will be a different version of the visit() method for each service class
• Each visit() method takes as its explicit parameter an instance of the service class that it applies to
![Page 20: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/20.jpg)
20
The Concrete Client Classes that Implement the Visitor Interface
• 2. The client side will develop concrete classes that implement the interface
• The concrete classes implement the versions of the visit() method for the service classes
• These concrete implementations of the method embody the new functionality that is to be added to/passed to the hierarchy of classes
• Keep in mind that the visit() methods take in service class objects as their explicit parameters
![Page 21: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/21.jpg)
21
The accept() Method in the Service Classes
• 3. Each class in the service hierarchy has to have an accept() method
• The accept() method takes an explicit parameter that is typed to the visitor interface
• When the accept() method is called on a service class object, a visitor object is passed in
![Page 22: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/22.jpg)
22
• Inside the accept() method, the visit() method is called on the explicit parameter that was passed in
• The explicit parameter that is sent to the visit() method is the service class object object that accept() was called on
![Page 23: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/23.jpg)
23
An Example with a Composite
• The UML diagram given on the overhead following the next one shows the MachineComponent composite hierarchy with visitation added
• The MachineComponent composite hierarchy is the service class hierarchy
• MachineComponent has an (abstract) accept() method
• Machine and MachineComposite have concrete accept() methods
![Page 24: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/24.jpg)
24
• The UML diagram also shows the MachineVisitor interface
• This interface contains two visit() methods• One visit() method takes a Machine object as
its explicit parameter• The other visit() method takes a
MachineComposite object as its explicit parameter
![Page 25: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/25.jpg)
25
![Page 26: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/26.jpg)
26
Fleshing Out MachineVisitor
• If client code is going to make use of visitation, it has to create concrete visitor classes
• These concrete visitor classes contain concrete implementations of the visit() methods
• The concrete visit() methods contain the functionality that is being “added to” the existing service hierarchy
• The functionality being added in this example is the ability to “find” a component in a composite
![Page 27: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/27.jpg)
27
• The UML diagram on the overhead following the next one shows a concrete class, FindVisitor
• It implements the MachinedVisitor interface• An instance of FindVisitor would be the object
passed as an explicit parameter when calling the accept() method on a Machine or MachineComposite object
![Page 28: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/28.jpg)
28
• FindVisitor has two versions of visit()• One version takes an instance of Machine as its
explicit parameter• The other takes an instance of
MachineComposite as its explicit parameter• FindVisitor also has an application specific
method, find()• How find() works depends on how visit() is coded
![Page 29: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/29.jpg)
29
![Page 30: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/30.jpg)
30
Another Example
• In order to follow the book’s example you would have to follow the logic of traversing the composite and implementing the logic of finding
• I don’t want to deal with those complexities• Therefore, the “other” example comes right
away• This is the example I want to pursue
![Page 31: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/31.jpg)
31
• The logic of this example is obtaining the name of a machine in reverse order
• This is simpler than implementing the logic of finding in a composite
• Also, I only do the implementation for a leaf• That way I avoid even having to consider
traversing the composite• The focus is on the Visitor pattern, not on the
complexities of the Composite pattern
![Page 32: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/32.jpg)
32
Machine Names
• Suppose that the Machine class has a String instance variable name and a getName() method
• Suppose that the class doesn’t have a getNameReversed() method, which would return the String name in reverse order, but this functionality is desired
![Page 33: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/33.jpg)
33
• Suppose that you don’t have access to the Machine class in order to implement this
• Suppose also that this is something that you might want to do more than once
• You don’t just want to call getName() in client code and then reverse the name every time the need arises in client code
• Instead, you’d like to package up the functionality in a visitor
![Page 34: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/34.jpg)
34
• Code will be given for a NameReversedVisitor class for getting the names of machine components in reversed order
• The class will contain two visit() methods, one for Machine and one for MachineComposite
• These methods actually contain the logic for reversing names
• Only the code for the Machine version will be given
![Page 35: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/35.jpg)
35
The Calling Sequence
• The NameReversedVisitor class will contain a descriptively named method, getNameReversed()
• Client code will construct an instance of NameReversedVisitor
• Client code will call getNameReversed() on that visitor
• Client code will pass a MachineComponent object as an explicit parameter to getNameReversed()
![Page 36: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/36.jpg)
36
• getNameReversed() calls accept() on the MachineComponent parameter (in the leaf case, a simple Machine)
• The version of accept() for a Machine will be called
• The accept() method calls visit() on the visitor and passes in “this” the machine that accept() was called on, as an implicit parameter
![Page 37: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/37.jpg)
37
• This verbal description is kind of hopelessly twisted
• Hopefully, it will be possible to follow the code• The code for the NameReversedVisitor class is
given on the next overhead• Remember that an implementation of visit() is
only given for the Machine class
![Page 38: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/38.jpg)
38
• public class NameReversedVisitor implements MachineVisitor• {• public String getNameReversed(MachineComponent mc)• {• mc.accept(this);• }• public String visit(Machine m)• {• String name = m.getName();• String retString = "";• for(int i = name.length() - 1; i >= 0; i--)• {• retString = retString + name.substring(i, i + 1);• }• return retString;• }• public String visit(MachineComposite machineCompositeIn)• {• // Some other implementation.• }• }
![Page 39: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/39.jpg)
39
• This is what accept() looks like:
• public void accept(MachineVisitor v)• {• v.visit(this);• }
![Page 40: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/40.jpg)
40
The Calling Sequence, Repeated
• The code execution sequence would go like this:• Client code constructs a machine visitor and a
machine• It calls the getNameReversed() method on the
visitor, passing in the machine• The implementation of getNameReversed()
consists of a call to the accept() method on the machine, passing in the visitor
![Page 41: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/41.jpg)
41
• The implementation of accept() consists of a call to the visit() method on the visitor, passing in the machine
• The visit() method contains logic that gets the name of the machine and returns a string containing the name in reversed order
![Page 42: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/42.jpg)
42
• I have provided no separate UML diagram for the other example
• It would be just like the book’s UML diagrams with the FindVisitor replaced by the ReversedNameVisitor
• The book’s example is going to be pursued in greater detail next, so the diagrams aren’t repeated here
• They will be shown again shortly
![Page 43: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/43.jpg)
43
A Critical Aspect of the Implementation of the Pattern
• This design pattern illustrates a subtle aspect of Java syntax that hasn’t come up before
• It has to do with where methods are declared and defined, and whether or not it is practical to inherit them
• It has specifically to do with the declaration and implementation of the visit() method and the call to visit() in the accept() method
![Page 44: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/44.jpg)
44
The MachineVisitor Interface
• The UML diagram for the Machine Component hierarchy and the MachineVisitor interface is shown again on the following overhead
• There are separate visit() methods, one that takes a Machine as its parameter, another that takes a MachineComposite as its parameter
• The visit() method declarations in the interface are shown on the overhead following the next one
![Page 45: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/45.jpg)
45
![Page 46: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/46.jpg)
46
• public interface MachineVisitor• {• void visit(Machine m);• void visit(MachineComposite mc);• }
![Page 47: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/47.jpg)
47
The accept() Method in the Service Classes (Composite Hierarchy)
• This was breezed over before, but the UML diagram has a mistake in it
• The accept(:MachineVisitor) method in the MachineComponent class should have been in italics, because this is the abstract method
• Its implementation is forced into the concrete subclasses Machine and MachineComposite
![Page 48: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/48.jpg)
48
• Now the book makes the following observation:• In each of the subclasses, Machine and
MachineComposite, the implementation of the accept() method is going to look exactly the same:
• public void accept(MachineVisitor v)• {• v.visit(this);• }
![Page 49: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/49.jpg)
49
• When you see this, you might think that the implementation of accept() can be pushed into the superclass (as implied by the mistake in the UML diagram)
• In other words, you might think that there is no need for it to be abstract in the MachineComponent class
• This is not the case
![Page 50: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/50.jpg)
50
• The compiler will see a difference between the implementations of the methods in the superclass and the two subclasses
• It all depends on the meaning of the term “this”, depending on the context in which it appears
![Page 51: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/51.jpg)
51
• Challenge 29.1• “What difference will a Java compiler see
between the accept() methods in the Machine and MachineComposite() classes?
• (Don’t peek on this one unless you have to; it’s key to understanding Visitor.)”
![Page 52: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/52.jpg)
52
• Solution 29.1• “The difference is in the type of the this object. • The accept() method calls the visit() method of a
MachineVisitor object. • The accept() method in the Machine class will look
up a visit() method with the signature visit(:Machine), whereas the accept() method in the MachineComposite class will look up a method with the signature visit(:MachineComposite).”
![Page 53: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/53.jpg)
53
• Comment mode on:• By studying the given code closely, it is possible to
answer the challenge correctly even without fully grasping what it means
• “this” is the only thing that could change between the two implementations of the method
• To tell the truth, at first glance I wasn’t completely convinced, so I looked into the alternative that the book rejected
![Page 54: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/54.jpg)
54
• What would happen if you did implement the accept() method in MachineComponent and let the two subclasses inherit it?
• Not only will the compiler see the difference in the correct solution
• It will tell you something is wrong with the incorrect solution
![Page 55: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/55.jpg)
55
• This is what’s in the MachineVisitor interface:
• public interface MachineVisitor• {• void visit(Machine m);• void visit(MachineComposite mc);• }
![Page 56: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/56.jpg)
56
• The accept() method would look exactly the same if you defined it in the abstract MachineComponent superclass and the concrete subclasses inherited it:
• public void accept(MachineVisitor v)• {• v.visit(this);• }
![Page 57: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/57.jpg)
57
What’s Wrong
• The compiler will tell you that it can’t find a version of the visit() method that takes an instance of MachineComponent as the explicit parameter
• In the MachineVisitor class there are only versions of visit() that take an instance of Machine or an instance of MachineComposite
![Page 58: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/58.jpg)
58
An Elaboration of What’s Wrong
• We have seen cases in the past where you can call a method with an explicit parameter typed to a superclass, and it’s OK to pass in an actual parameter object that is of a subclass
• In a sense, this is the reverse of that situation• You are trying to call a method with an explicit
parameter of a superclass type, when the only implementations of the method have subclass formal parameters
![Page 59: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/59.jpg)
59
• You can’t pass a superclass parameter to something that is typed to accept a subclass
• That is, you can’t have a subclass reference to a superclass type, (unless it’s a situation where you can check the reference type with instanceof and recover the subclass reference by casting)
![Page 60: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/60.jpg)
60
• Consider this “reverse” case of superclass/subclass parameter passing again
• It’s really a question about overloading• You have various versions of the method that
are distinguished by their parameter types
![Page 61: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/61.jpg)
61
• Syntactically, the problem is that there isn’t a version with a superclass parameter
• Logically, there shouldn’t be one—so all is well• This just means that you have to push the
implementations into the subclasses, as shown
![Page 62: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/62.jpg)
62
Potential Shortcomings of the Pattern
• This design pattern has certain shortcomings• The UML diagram showing a concrete visitor
class is repeated on the following overhead for reference
![Page 63: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/63.jpg)
63
![Page 64: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/64.jpg)
64
• This is the motivating idea:• The machine composite hierarchy doesn’t
implement a find() method• The desire arises to have one, without
implementing it in the machine composite hierarchy
• This can be done by means of a visitor
![Page 65: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/65.jpg)
65
• The first thing you might observe about the pattern is that it’s kind of round-about
• The visit() and accept() methods are essentially intertwined
![Page 66: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/66.jpg)
66
• The service classes have accept() methods• Those accept() methods take instances of visitor
objects• The visitor objects have versions of the visit()
method with a parameter for each of the service classes
• For a given service object, inside the body of accept(), visit() is called on the visitor, passing in “this” as the explicit parameter
![Page 67: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/67.jpg)
67
• This intertwinement is unavoidable when you are trying to meet these conditions:
• You can’t change the service code class• You still want to package up the functionality
so that it can be used more than once
![Page 68: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/68.jpg)
68
Is This a Good Idea?
• The next consideration is whether this is a good idea at all
• In order to implement find() in the book’s example it is necessary to traverse a composite data structure using visit()
• The underlying operation is to find a given node in the structure, but different versions of visit() are needed for machines and machine composites
![Page 69: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/69.jpg)
69
• This example illustrates the fundamental shortcoming of the design pattern
• As an outsider, without access to the service class’s internals, how do you know how to correctly traverse the structures?
• Do you know, for example, whether cycles are allowed, and whether you’ll have to handle them?
• Remember the discussion of isTree() when presenting the Composite pattern
![Page 70: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/70.jpg)
70
• If traversal is so important, why wasn’t it built into the class?
• If there are potential pitfalls, shouldn’t the code be implemented in the service class and not externally?
• Why can’t it be added to the class now?• Why has the correct handling of a potentially
problematic situation suddenly become the responsibility of someone who is writing client code?
![Page 71: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/71.jpg)
71
• There are no ultimate answers to these questions
• Some people think the pattern is useful• Others think it’s not• In the long run, I think it’s worth covering not
because of its intent, but because of the point made at the beginning about Java syntax and compilation
![Page 72: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/72.jpg)
72
• It is important to keep careful track of how the compiler tells things apart
• This can affect where in an inheritance hierarchy you implement methods that look the same
• It was not a trick, but really, a special case• The methods looked the same because they both
referred to “this”, but “this” in two different classes will be two different kinds of objects
![Page 73: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/73.jpg)
73
Lasater’s UML
• Lasater’s diagram, this time, does not seem as informative as the book’s diagrams
• It includes a client, but it shows closed arrowheads from client to visitor and from client to object structure to element
• I’m pretty sure he was daydreaming and these should be open arrowheads
• It is apparent that there are accept() and visit() methods, but otherwise the diagram is not very helpful
![Page 74: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/74.jpg)
74
![Page 75: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/75.jpg)
75
One Last Remark at the End of the Composite Based Patterns—Don’t Skip This
• The visitor pattern is the last of the patterns related to composite as presented in the overheads for the units in the course
• This is just a last remark having to do with composites
• You may recall the unit on the Iterator pattern
![Page 76: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/76.jpg)
76
• The book chapter on the Iterator came after the chapter on composites
• This meant that the book could cover iteration over a composite and I did not do so in the unit on iteration
• In theory it would be possible to have one last section, in order to cover iteration over a composite now
![Page 77: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/77.jpg)
77
• This would make for a pretty comprehensive treatment of composites
• I will not cover it in these overheads and there will be no extra unit on this
• The main point of mentioning this is that you should still have some grasp of iteration when taking the last test
• There is a possibility that iteration will come again in the context of composites
![Page 78: Unit 28 Visitor](https://reader033.vdocuments.us/reader033/viewer/2022051219/56815f4a550346895dce2798/html5/thumbnails/78.jpg)
78
The End