一、简介
访问者模式允许一个或者多个操作应用到一组对象上,设计意图是解耦操作和对象本身,保持类职责单一、满足开闭原则以及应对代码的复杂性。
二、优点
- 分离操作和数据结构
- 增加新操作更容易
- 集中化操作
三、适用场景
- 数据结构稳定,操作易变
- 一个对象的操作之间无关联
四、UML类图
五、案例
有圆形和矩形两种对象,有画图和调整大小两种数据访问者对形状进行处理。
package mainimport "fmt"type Shape interface {Accept(visitor Visitor)GetType() string
}type Circle struct {
}func NewCircle() *Circle {return &Circle{}
}func (c *Circle) Accept(visitor Visitor) {visitor.Visit(c)
}func (c *Circle) GetType() string {return "Circle"
}type Rectangle struct {
}func NewRectangle() *Rectangle {return &Rectangle{}
}func (r *Rectangle) Accept(visitor Visitor) {visitor.Visit(r)
}func (r *Rectangle) GetType() string {return "Rectangle"
}type Visitor interface {Visit(shape Shape)
}type DrawVisitor struct {
}func NewDrawVisitor() *DrawVisitor {return &DrawVisitor{}
}func (dv *DrawVisitor) Visit(shape Shape) {if shape.GetType() == "Circle" {fmt.Println("Drawing a circle")} else if shape.GetType() == "Rectangle" {fmt.Println("Drawing a rectangle")} else {fmt.Println("Unknown shape")}
}type ResizeVisitor struct {
}func NewResizeVisitor() *ResizeVisitor {return &ResizeVisitor{}
}func (rv *ResizeVisitor) Visit(shape Shape) {if shape.GetType() == "Circle" {fmt.Println("Resizing a circle")} else if shape.GetType() == "Rectangle" {fmt.Println("Resizing a rectangle")} else {fmt.Println("Unknown shape")}
}func main() {circle := NewCircle()rectangle := NewRectangle()drawVisitor := NewDrawVisitor()resizeVisitor := NewResizeVisitor()circle.Accept(drawVisitor)circle.Accept(resizeVisitor)rectangle.Accept(drawVisitor)rectangle.Accept(resizeVisitor)
}