访问者模式是一种行为设计模式,它能将算法与其所作用的对象隔离开来。
解决什么问题?
- 如果你需要对一个复杂对象结构 (例如对象树) 中的所有元素执行某些操作, 可使用访问者模式。
- 可使用访问者模式来清理辅助行为的业务逻辑。
- 当某个行为仅在类层次结构中的一些类中有意义, 而在其他类中没有意义时, 可使用该模式。
优势:
- 开闭原则。 你可以引入在不同类对象上执行的新行为, 且无需对这些类做出修改。
- 单一职责原则。 可将同一行为的不同版本移到同一个类中。
- 访问者对象可以在与各种对象交互时收集一些有用的信息。 当你想要遍历一些复杂的对象结构 (例如对象树), 并在结构中的每个对象上应用访问者时, 这些信息可能会有所帮助。
劣势:
- 每次在元素层次结构中添加或移除一个类时, 你都要更新所有的访问者。
- 在访问者同某个元素进行交互时, 它们可能没有访问元素私有成员变量和方法的必要权限。
实现步骤:
- 定义访问者接口
- 定义访问者实体类,并实现访问者接口
- 在被访问者类中关联访问者类,将被访问者对象自身作为参数传递给访问者对象
下面是实现代码:
package main
import "fmt"
type visitor interface {
visitCircle(c *circle)
visitRectangle(r *rectangle)
}
type shape interface {
accept(v visitor)
}
type xmlExportVisitor struct{}
func (x *xmlExportVisitor) visitCircle(c *circle) {
fmt.Println("export circle shape as xml format")
}
func (x *xmlExportVisitor) visitRectangle(r *rectangle) {
fmt.Println("export rectangle shape as xml format")
}
type circle struct{}
func (c *circle) accept(v visitor) {
v.visitCircle(c)
}
type rectangle struct{}
func (r *rectangle) accept(v visitor) {
v.visitRectangle(r)
}
func main() {
xml := xmlExportVisitor{}
c := circle{}
c.accept(&xml)
r := rectangle{}
r.accept(&xml)
}
输出:
export circle shape as xml format
export rectangle shape as xml format