1 定义
允许一个或者多个操作应用到一组对象上,解耦操作和对象本身
2 例子
访问者模式比较复杂,适合特殊场景。如下图,假设有某个接口有若干个实现类(A, B, C),Visitor1想操作这些实现类(通过方法method1()
)。而且不同的实现类所执行的方法体不同,无法将method1()
方法放到父类。
一种简单的方法是直接在若干实现类里写method1()
。这样的问题是:
- 不满足开闭原则,每次有新的Visitor,都需要同时修改若干个实现类。
- 可能不满足单一职责,Visitor的方法也许与实现类本身的功能无关,却写在一个类里。Visitor的方法应该写在单独的Visitor类里。
- 如果Visitor数量很多(比如达到100个),那么实现类的代码行数特别多,不容易读。
这种极端场景下就很适合访问者模式。如下图,不在实现类(A, B, C)里写method()
。单独的Visitor类实现对A,B,C的访问。它完美解决上述问题。
下面是个python脚本。脚本依赖plum-dispatch包。
from plum import dispatch
from abc import ABCMeta, ABC, abstractmethod
class PetVisitor(ABC):
@abstractmethod
def visit_pet(self, dog: 'Dog') -> None:
pass
@abstractmethod
def visit_pet(self, cat: 'Cat') -> None:
pass
class PetFeeder(PetVisitor):
@dispatch
def visit_pet(self, dog: 'Dog') -> None:
print(f'为宠物: {
dog.get_dog_name()}添加狗粮')
@dispatch
def visit_pet(self, cat: 'Cat') -> None:
print(f'为宠物: {
cat