mirror of
https://github.com/tmrts/go-patterns.git
synced 2024-11-29 08:26:10 +03:00
behavioral/visitor: implement visitor pattern
This commit is contained in:
parent
f978e42036
commit
8cbceb99c5
80
behavioral/visitor.md
Normal file
80
behavioral/visitor.md
Normal file
@ -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(`<circle><radius>%d</radius></circle>`, circle.Rad)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*XmlVisitor) visitLine(line Line) string {
|
||||||
|
return fmt.Sprintf(`<line><length>%d</length></line>`, line.Len)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
circle := Circle{12}
|
||||||
|
line := Line{42}
|
||||||
|
xmlVisitor := XmlVisitor{}
|
||||||
|
fmt.Println(circle.accept(&xmlVisitor))
|
||||||
|
fmt.Println(line.accept(&xmlVisitor))
|
||||||
|
```
|
64
behavioral/visitor/main.go
Normal file
64
behavioral/visitor/main.go
Normal file
@ -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(`<circle><radius>%d</radius></circle>`, circle.Rad)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*XmlVisitor) visitLine(line Line) string {
|
||||||
|
return fmt.Sprintf(`<line><length>%d</length></line>`, 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))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user