设计模式笔记 - 访问者模式

139 阅读2分钟

访问者模式是一种行为设计模式,它能将算法与其所作用的对象隔离开来。


解决什么问题?

  • 如果你需要对一个复杂对象结构 (例如对象树) 中的所有元素执行某些操作, 可使用访问者模式。
  • 可使用访问者模式来清理辅助行为的业务逻辑。
  • 当某个行为仅在类层次结构中的一些类中有意义, 而在其他类中没有意义时, 可使用该模式。

优势:

  • 开闭原则。 你可以引入在不同类对象上执行的新行为, 且无需对这些类做出修改。
  • 单一职责原则。 可将同一行为的不同版本移到同一个类中。
  • 访问者对象可以在与各种对象交互时收集一些有用的信息。 当你想要遍历一些复杂的对象结构 (例如对象树), 并在结构中的每个对象上应用访问者时, 这些信息可能会有所帮助。

劣势:

  • 每次在元素层次结构中添加或移除一个类时, 你都要更新所有的访问者。
  • 在访问者同某个元素进行交互时, 它们可能没有访问元素私有成员变量和方法的必要权限。

实现步骤:

  • 定义访问者接口
  • 定义访问者实体类,并实现访问者接口
  • 在被访问者类中关联访问者类,将被访问者对象自身作为参数传递给访问者对象

下面是实现代码:

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

参考