mirror of
https://github.com/tmrts/go-patterns.git
synced 2024-12-01 17:26:03 +03:00
81 lines
1.5 KiB
Markdown
81 lines
1.5 KiB
Markdown
|
# 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))
|
||
|
```
|