diff --git a/behavioral/visitor.md b/behavioral/visitor.md new file mode 100644 index 0000000..48a1088 --- /dev/null +++ b/behavioral/visitor.md @@ -0,0 +1,80 @@ +# Visitor Pattern +Visitor behavioral design pattern provides a way to separate an algorithm from an object on which it operates. + +It gives the ability to extend the existing object without modifying the object itself. + +## Implementation + +```go +type Visitor interface { + visitCircle(circle Circle) string + visitLine(line Line) string +} + +type Shape interface { + accept(Visitor) string +} + +type Circle struct { + Rad int +} + +func (c Circle) accept(v Visitor) string { + return v.visitCircle(c) +} + +type Line struct { + Len int +} + +func (l Line) accept(v Visitor) string { + return v.visitLine(l) +} +``` + +## Usage +### JSON marshaller + +```go +type JsonVisitor struct { +} + +func (*JsonVisitor) visitCircle(circle Circle) string { + return fmt.Sprintf(`{"type": "circle", "radius": "%v"}`, circle.Rad) +} + +func (*JsonVisitor) visitLine(line Line) string { + return fmt.Sprintf(`{"type": "line", "length": "%v"}`, line.Len) +} +``` + +```go +circle := Circle{12} +line := Line{42} +jsonVisitor := JsonVisitor{} +fmt.Println(circle.accept(&jsonVisitor)) +fmt.Println(line.accept(&jsonVisitor)) +``` + +### XML marshaller + +```go +type XmlVisitor struct { +} + +func (*XmlVisitor) visitCircle(circle Circle) string { + return fmt.Sprintf(`%d`, circle.Rad) +} + +func (*XmlVisitor) visitLine(line Line) string { + return fmt.Sprintf(`%d`, line.Len) +} +``` + +```go +circle := Circle{12} +line := Line{42} +xmlVisitor := XmlVisitor{} +fmt.Println(circle.accept(&xmlVisitor)) +fmt.Println(line.accept(&xmlVisitor)) +``` diff --git a/behavioral/visitor/main.go b/behavioral/visitor/main.go new file mode 100644 index 0000000..db9aa93 --- /dev/null +++ b/behavioral/visitor/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" +) + +type Visitor interface { + visitCircle(circle Circle) string + visitLine(line Line) string +} + +type Shape interface { + accept(Visitor) string +} + +type Circle struct { + Rad int +} + +func (c Circle) accept(v Visitor) string { + return v.visitCircle(c) +} + +type Line struct { + Len int +} + +func (l Line) accept(v Visitor) string { + return v.visitLine(l) +} + +type JsonVisitor struct { +} + +func (*JsonVisitor) visitCircle(circle Circle) string { + return fmt.Sprintf(`{"type": "circle", "radius": "%v"}`, circle.Rad) +} + +func (*JsonVisitor) visitLine(line Line) string { + return fmt.Sprintf(`{"type": "line", "length": "%v"}`, line.Len) +} + +type XmlVisitor struct { +} + +func (*XmlVisitor) visitCircle(circle Circle) string { + return fmt.Sprintf(`%d`, circle.Rad) +} + +func (*XmlVisitor) visitLine(line Line) string { + return fmt.Sprintf(`%d`, line.Len) +} + +func main() { + circle := Circle{12} + line := Line{42} + jsonVisitor := JsonVisitor{} + fmt.Println(circle.accept(&jsonVisitor)) + fmt.Println(line.accept(&jsonVisitor)) + + xmlVisitor := XmlVisitor{} + fmt.Println(circle.accept(&xmlVisitor)) + fmt.Println(line.accept(&xmlVisitor)) +}