概述
- Visitor 模式是将
算法和结构分离的一种方法
- 在
不修改结构的情况下,向现有对象结构添加新操作,遵循 OCP
- 不同 Visitor 用来访问同一个数据结构的不同部分
示例 1
类似于 Java java.util.function.Consumer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| type Visitor func(shape Shape)
type Shape interface { accept(Visitor) }
type Circle struct { Radius int }
func (c *Circle) accept(v Visitor) { v(c) }
type Rectangle struct { Width, Height int }
func (r *Rectangle) accept(v Visitor) { v(r) }
func JsonVisitor(shape Shape) { bytes, err := json.Marshal(shape) if err != nil { panic(err) } fmt.Println(string(bytes)) }
func XmlVisitor(shape Shape) { bytes, err := xml.Marshal(shape) if err != nil { panic(err) } fmt.Println(string(bytes)) }
func main() { c := Circle{10} r := Rectangle{10, 20}
for _, shape := range []Shape{&c, &r} { shape.accept(JsonVisitor) shape.accept(XmlVisitor) } }
|
示例 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| type Info struct { Name string Namespace string }
type VisitorFunc func(*Info, error) error
type Visitor interface { Visit(VisitorFunc) error }
func (info *Info) Visit(f VisitorFunc) error { return f(info, nil) }
type NameVisitor struct { visitor Visitor }
func (v *NameVisitor) Visit(f VisitorFunc) error { return v.visitor.Visit(func(info *Info, err error) error { err = f(info, err) if err != nil { return err } fmt.Printf("Name: %s\n", info.Name) return nil }) }
type NamespaceVisitor struct { visitor Visitor }
func (v *NamespaceVisitor) Visit(f VisitorFunc) error { return v.visitor.Visit(func(info *Info, err error) error { err = f(info, err) if err != nil { return err } fmt.Printf("Namespace: %s\n", info.Namespace) return nil }) }
func main() { info := Info{ Name: "app", Namespace: "default", } var v Visitor = &info v = &NameVisitor{v} v = &NamespaceVisitor{v}
_ = v.Visit(func(info *Info, err error) error { return nil }) }
|