访问者模式是指封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作.
参与者:
Visitor(访问者) :为该对象结构中 ConcreteElement的每一个类声明一个 Visit操作.该操作的名字和特征标识了发送 Visit请求给该访问者的那个类.这使得访问者可以确定正被访问元素 的具体的类.这样访问者就可以通过该元素的特定接口直接访问它.
ConcreteVisitor(具体访问者): 实现每个由 Visitor声明的操作.每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储它的局部状态.这一状态常常在遍历该结构的过程中累积结果.
Element(元素) :定义一个Accept操作,它以一个访问者为参数。
ConcreteElement(具体元素) :实现Accept操作,该操作以一个访问者为参数.
ObjectStructure(对象结构) :能枚举它的元素,可以提供一个高层的接口以允许该访问者访问它的元素, 可以是一个复合(参见Composite组合模式)或是一个集合,如一个列表或一个无序集合.
元素的基类定义为Person:
class Person {
func accept(visitor:PlaceVisitor) {}
}
class Boss:Person {
override func accept(visitor: PlaceVisitor) {
visitor.visitor(boss: self)
}
}
class Employee:Person {
override func accept(visitor: PlaceVisitor) {
visitor.visitor(employee: self)
}
}
定义访问行为:
class PlaceVisitor {
func visitor(boss:Boss) {}
func visitor(employee:Employee) {}
}
class HouseVisitor:PlaceVisitor {
override func visitor(boss: Boss) {
print("老板在家埋头工作")
}
override func visitor(employee: Employee) {
print("员工在家看电视聊天")
}
}
class OfficeVisitor:PlaceVisitor {
override func visitor(boss: Boss) {
print("老板在办公室进行商务拓展")
}
override func visitor(employee: Employee) {
print("员工在办公室认真工作")
}
}
客户端调用:
let boss:Boss = Boss()
let employee:Employee = Employee()
let houseVisitor:PlaceVisitor = HouseVisitor()
let officeVisitor:PlaceVisitor = OfficeVisitor()
boss.accept(visitor: houseVisitor)
employee.accept(visitor: houseVisitor)
boss.accept(visitor: officeVisitor)
employee.accept(visitor: officeVisitor)
访问者不同的一般的设计模式,开发中的实际场景相对较少,设计模式的作者GoF对访问者模式的描述:大多数情况下,你并需要使用访问者模式,但是当你一旦需要使用它时,那你就是真的需要它了.虽然场景不多,但是访问者模式能将行为从对象中进行抽离,符合单一职责原则,并且有更好的扩展性.
参考资料:
访问者模式