-
Notifications
You must be signed in to change notification settings - Fork 109
/
Visitor.kt
116 lines (94 loc) · 3.14 KB
/
Visitor.kt
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
115
package design_patterns
/**
*
* Visitor is a behavioral design pattern that allows you to add a new operation
*
* to an entire class hierarchy without changing the code of these classes.
*
*/
interface PonyVisitor {
fun visitPonies(vararg ponies: LittlePony) : String
fun visitEarthPony(pony: EarthPony) : String
fun visitUnicorn(pony: Unicorn) : String
fun visitPegasus(pony: Pegasus) : String
}
class JsonVisitor : PonyVisitor {
override fun visitPonies(vararg ponies: LittlePony) : String {
val poniesString = ponies.joinToString(",\n") { pony -> pony.accept(this) }
return "[$poniesString]"
}
override fun visitEarthPony(pony: EarthPony): String {
return """
{
"what" : "earth pony",
"name" : "${pony.name()}",
"cutie_mark" : "${pony.cutie()}
}
""".trimIndent()
}
override fun visitUnicorn(pony: Unicorn): String {
return """
{
"what" : "unicorn",
"name" : "${pony.name()}",
"cutie_mark" : "${pony.cutie()}
}
""".trimIndent()
}
override fun visitPegasus(pony: Pegasus): String {
return """
{
"what" : "pegasus",
"name" : "${pony.name()}",
"cutie_mark" : "${pony.cutie()}
}
""".trimIndent()
}
}
class XmlVisitor : PonyVisitor {
override fun visitPonies(vararg ponies: LittlePony) : String {
val poniesString = ponies.joinToString("\n") { pony -> pony.accept(this) }
return "<ponies>\n$poniesString\n</ponies>"
}
override fun visitEarthPony(pony: EarthPony): String {
return """
<pony>
<what>earth pony</what>
<name>${pony.name()}</name>
<cutie_mark>${pony.cutie()}</cutie_mark>
</pony>
""".trimIndent()
}
override fun visitUnicorn(pony: Unicorn): String {
return """
<pony>
<what>unicorn</what>
<name>${pony.name()}</name>
<cutie_mark>${pony.cutie()}</cutie_mark>
</pony>
""".trimIndent()
}
override fun visitPegasus(pony: Pegasus): String {
return """
<pony>
<what>pegasus</what>
<name>${pony.name()}</name>
<cutie_mark>${pony.cutie()}</cutie_mark>
</pony>
""".trimIndent()
}
}
abstract class LittlePony(private val name: String, private val cutieMark: String) {
fun name() = name
fun cutie() = cutieMark
abstract fun accept(visitor: PonyVisitor) : String
}
class EarthPony(name: String, cutieMark: String) : LittlePony(name, cutieMark) {
override fun accept(visitor: PonyVisitor) = visitor.visitEarthPony(this)
}
class Unicorn(name: String, cutieMark: String) : LittlePony(name, cutieMark) {
override fun accept(visitor: PonyVisitor) = visitor.visitUnicorn(this)
}
class Pegasus(name: String, cutieMark: String) : LittlePony(name, cutieMark) {
override fun accept(visitor: PonyVisitor) = visitor.visitPegasus(this)
}