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