/
visitor.rb
executable file
·115 lines (94 loc) · 2.44 KB
/
visitor.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# example of the visitor pattern pretending ruby is like java
# The class hierachy that needs additional functionality needs to have an Accept method
# that takes a pre-defined interface. This is the main problem, the designer has to build Visitor in up front for it to work
# with languages like Java.
# pretending to be a java interface
module TreeVisitor
def visit(tree)
end
end
# have you ever had pure maple sap?
class SyrupVisitor
include TreeVisitor
def visit(tree)
if tree.is_a? Oak
puts "#{tree.gatherAcorns} is stupid!"
elsif tree.is_a? Ash
puts "#{tree.eatAshBoringBeetle} is gross!"
elsif tree.is_a? SugarMaple
puts "#{tree.drinkingSyrup} is better than any energy drink I have ever had!"
end
end
end
# storing nuts for the winter
class SquirrelVisitor
include TreeVisitor
def visit(tree)
if tree.is_a? Oak
puts "#{tree.gatherAcorns} is what I do to survive!"
elsif tree.is_a? Ash
puts "#{tree.eatAshBoringBeetle} can be OK, if you are starving to death!"
elsif tree.is_a? SugarMaple
puts "#{tree.drinkingSyrup} is impossible for me most of the time!"
end
end
end
# eating bugs with a stick
class CrowVisitor
include TreeVisitor
def visit(tree)
if tree.is_a? Oak
puts "#{tree.gatherAcorns} is pointless!"
elsif tree.is_a? Ash
puts "#{tree.eatAshBoringBeetle} makes you grow black hair on your chest!"
elsif tree.is_a? SugarMaple
puts "#{tree.drinkingSyrup} does not do anything for me unless it is fermented!"
end
end
end
# these classes do not share the object hierarchy on purpose to show
# how visitor is used to visit a heterogeneous hierarchy (in java for instance)
class Oak
def accept(visitor)
visitor.visit(self)
end
def gatherAcorns
puts 'gathering acorns'
end
end
class Ash
def accept(visitor)
visitor.visit(self)
end
def eatAshBoringBeetle
puts "eating ash boring beetles"
end
end
class SugarMaple
def accept(visitor)
visitor.visit(self)
end
def drinkingSyrup
puts "drinking pure maple sap"
end
end
syrupGuy = SyrupVisitor.new
sq = SquirrelVisitor.new
crow = CrowVisitor.new
oak = Oak.new
ash = Ash.new
maple = SugarMaple.new
puts "syrup guy says:"
oak.accept(syrupGuy)
ash.accept(syrupGuy)
maple.accept(syrupGuy)
puts ""
puts "happy jack says:"
oak.accept(sq)
ash.accept(sq)
maple.accept(sq)
puts ""
puts "crow says:"
oak.accept(crow)
ash.accept(crow)
maple.accept(crow)