此模式一般作用於数据结构中對各元素之操作,它可使在不改变各元素的前提下重新定义作用于这些元素的新操作,故可将数据結构與数据处理解耦,讓数据結构只提供数据处理的接口,此数据結构的处理者便是访问者,日後只要数据结构要面临不同处理的结果时,只需要创建不同的访问者即可。
UML类图:
示例:
# encoding=utf-8
import abc
class Program: #基于数据结构的基类
@abc.abstractclassmethod
def Accept(self, visitor):
raise NotImplementedError
class Python(Program): #具体子类1
name = 'python'
def Accept(self, visitor):
visitor.operationPython(self)
class Javascript(Program): #具体子类2
name = 'javascript'
def Accept(self, visitor):
visitor.operationJavascript(self)
class Visitor: #基于数据结构的訪問者抽象基类
@abc.abstractclassmethod
def operationPython(self, program):
raise NotImplementedError
@abc.abstractclassmethod
def operationJavascript(self, program):
raise NotImplementedError
class Operation1(Visitor): #訪問者具体类1(*即操作类1)
name = 'operation1'
def operationPython(self, program):
print('以%s調用訪問者%s()方法' % (program.name, self.name))
def operationJavascript(self, program):
print('以%s調用訪問者%s()方法' % (program.name, self.name))
class Operation2(Visitor): #訪問者具体类2(*即操作类2)
name = 'operation2'
def operationPython(self, program):
print('以%s調用訪問者%s()方法' % (program.name, self.name))
def operationJavascript(self, program):
print('以%s調用訪問者%s()方法' % (program.name, self.name))
class Operation3(Visitor): #訪問者具体类3(*即操作类3)
name = 'operation3'
def operationPython(self, program):
print('以%s調用訪問者%s()方法' % (program.name, self.name))
def operationJavascript(self, program):
print('以%s調用訪問者%s()方法' % (program.name, self.name))
class LanguageStructure: #数据结构类
elements = []
def Attach(self, element):
self.elements.append(element)
def Detach(self, element):
self.elements.remove(element)
def Display(self, visitor):
for e in self.elements:
e.Accept(visitor)
#實際業務邏輯之場景如下:
def clientUI():
# 建置数据结构
ls = LanguageStructure()
ls.Attach(Python())
ls.Attach(Javascript())
# 遍历数据结构的訪問者操作
ls.Display(Operation1())
ls.Display(Operation2())
ls.Display(Operation3())
if __name__ == '__main__':
clientUI();
輸出:
以python調用訪問者operation1()方法
以javascript調用訪問者operation1()方法
以python調用訪問者operation2()方法
以javascript調用訪問者operation2()方法
以python調用訪問者operation3()方法
以javascript調用訪問者operation3()方法
總結:
访问者模式适用於数据结构相对稳定而基于该数据结构的訪問操作需要经常扩展的系统,因此模式的优点就是相对很容易增加新的訪問操作。访问者模式是常用设计模式中难度最大的一种模式,难度在於高度抽象及其多层嵌套,需要细心品味才能箇知其中道理。