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))
+}