来源于B站极客架构师老吴大佬
属于行为型模式
定义
Represent an operation to be performed on the elements of an object structure.Visitor lets you define a new operation without changing the classes of the elements on which it operates.——Gof《Design Patterns: Elements of Reusable Object-Oriented Software》
表示一个作用于某对象结构中的各元素的操作。它使你在不改变各元素的类的前提下定义作用于这些元素的新操作。
——Gof《设计模式:可复用面向对象软件的基础》
对象结构
这里的“对象结构”,可以理解为常见的集合,如List,Set,Map等,或者树结构,比如编译器项目里面的抽象语法树。
元素
而对象结构中包含的对象,即是“元素”。
操作
而“元素”的“操作”,当然就是我们熟悉的方法了。
总结
这个定义的第一句,以动词“表示”开头,缺少主语,大家一定要搞清楚主语是什么,这个主语,就是访问者模式里面的访问者角色。
所以,访问者模式的定义,用面向对象语言中我们熟悉的语言解释,就是,
用访问者角色对象表示一个集合中各个元素的方法。它的宗旨就是在不改变数据结构中元素类的前提下,扩展元素的方法。
既要不改变类,又要扩展类的方法,看似挺矛盾的,其实结合我们上面的案例看,就不足为奇了。
我的理解
就是人民币有很多面值,纸币,硬币。纸币有0.5,1,5,10,100的面值,硬币有0.1,0.5,1,他们的重量是不同的。
现在我们有许多面值对象,就是被访问者。现在我们要统计它们的总钱数是多少?总总量是多少?
我们这种统计的不同要求,就相当于是一个访问者。按照我们通用的做法,就是循环面值对象,定义二个变量,根据不同的面值,去累加不同的值,然后得出结果。以后再出现新的统计需求,在加方法去实现。但是如果要变成实时统计了呢?就是中途加一个访问者,立马要得出截止到当前的钱数和总量,这时候怎么做了呢?
用了访问者模式之后,我们就可以将一个统计请求做成一个访问者,我们有硬币,纸币两种不同对象,就定义2个visit方法,入参是被访问者,之后根据访问者的不同属性做相应计算。这样就将通用做法里面不同对象的判断加不同的值,进行解耦,方便维护。
相当于以前的一个方法,变成一个类,里面有n个方法。看起来代码是增加的,但是逻辑处理起来更新清楚,便与维护。