type Node interface {
IsNode()
}
type DotNode struct{}
func (d *DotNode) IsNode() {}
type CircleNode struct{}
func (c *CircleNode) IsNode() {}
type RectangleNode struct{}
func (r *RectangleNode) IsNode() {}
type CompoundNode struct{}
func (c *CompoundNode) IsNode() {}
type Visitor interface {
Visit(Node)
}
type Visitor1 struct{}
func (v *Visitor1) Visit(n Node) {
switch n.(type) { // a Visitor doesn't have to visit all Node type
case *DotNode:
fmt.Println("visitor1 visiting a DotNode")
case *CircleNode:
fmt.Println("visitor1 visiting a CircleNode")
case *CompoundNode:
fmt.Println("visitor1 visiting a CompoundNode")
}
}
type Visitor2 struct{}
func (v *Visitor2) Visit(n Node) {
switch n.(type) { // a Visitor doesn't have to visit all Node type
case *CircleNode:
fmt.Println("visitor2 visiting a CircleNode")
case *RectangleNode:
fmt.Println("visitor2 visiting a RectangleNode")
}
}
visitor_test.go:
func Example_visitor() {
nodes := []visitor.Node{
&visitor.DotNode{},
&visitor.CircleNode{},
&visitor.RectangleNode{},
&visitor.CompoundNode{},
}
visitor1 := &visitor.Visitor1{}
for _, n := range nodes {
visitor1.Visit(n)
}
fmt.Println()
visitor2 := &visitor.Visitor2{}
for _, n := range nodes {
visitor2.Visit(n)
}
// Output:
// visitor1 visiting a DotNode
// visitor1 visiting a CircleNode
// visitor1 visiting a CompoundNode
//
// visitor2 visiting a CircleNode
// visitor2 visiting a RectangleNode
}
Visitor 模式可以在不改变现有类的情况下,为其添加新的行为(第二种说法:可以将算法与操作对象分离)。
一个简单的实现
visitor.go:
visitor_test.go:
See also