浅析设计模式:访问者模式(Visitor)

    访问者模式被应用于解决这一类问题:

    数据结构中保存着许多元素,对这些元素的处理应该放在什么地方?通常我们最常见的做法就是将这些处理直接放在表示数据结构的类中,当然在很多情况下这算是一种最简单便捷的方式了,例如java集合中也有很多对元素操作的方法是放在集合类中的。但是,当需要经常增加一些处理时,我们就不难发现这种方式存在弊端,即每次增加处理,都需要修改表示数据结构的类,这显然违背了“开闭原则”!

开闭原则:对扩展开放,对修改关闭,提倡在不修改已有类的前提下扩展新的功能。

    怎么解决这类问题?将数据结构与处理分开不就好了!表示数据结构的类只需要提供对"访问者"开放的接口(API),而对元素的处理则由访问者负责,当需要新增一种对元素的处理方式时,只需要编写新的表示访问者的类即可,这样就无需对表示数据结构的类(原有的代码)进行修改,又扩展出了新功能。


访问者模式中的角色:

  • Visitor:表示访问者的抽象类,用于声明对数据结构中xxx元素访问的visit(xxx)方法。
  • ConcreteVisitor:表示具体的访问者,继承Visitor并对其声明的抽象方法提供具体实现。
  • Element:表示元素的抽象类,即访问者实际要访问的对象,Element角色需要对访问者提供一个开放的接口,即accept方法,该方法的参数就是Visitor角色。
  • ConcreteElement:表示具体的元素,提供accept方法的实现。
  • ObjectStructure:负责处理Element元素的集合,即表示数据结构的类。

是的很抽象,我们来看下它们之间的类图关系:



接下来动手实践,我们来模拟这样一个场景:

    有一片果园,果园里已经挖好了大大小小的坑,假设大的坑用来种苹果树,小的坑用来种桔子树。类比于上述观察者模式中的 角色我们不难发现,大的坑和小的坑分别表示两种具体的元素ConcreteElement,树农表示访问者(ConcreteVisitor),坑需要接受树农的访问,而果园就是容纳这些坑的数据结构。

1、编写访问者的抽象类(Visitor):

扫描二维码关注公众号,回复: 1533750 查看本文章

    代表果农这一角色,声明了对不同坑(Element)作不同处理的方法。


2、编写具体的访问者(ConcreteVisitor):

   对Visitor中的抽象方法提供具体实现。


3、编写元素的抽象类(Element):

   本案例中的元素就是大大小小的坑,声明一个抽象方法,表示接受树农的访问。


4、编写具体的元素类(ConcreteElement):

  苹果树坑和桔子树坑都实现accept方法,接受树农访问自己。


5、编写表示数据结构的类(ObjectStructure):


6、最后编写测试类:


    最后总结一下,访问者模式就是用于将数据结构和对元素的处理分离开来,当需要对元素添加新的处理,只需要新增访问者,在访问者中提供新的处理方法,而不需要修改表示数据结构的类本身,这很好的满足了"开闭原则"。

    但是有一点需要注意:新增访问者容易,但是新增元素就很困难了!假设你要新增一个梨树坑,你要怎么做?你需要在Farmer类(Visitor)中新增一个方法plant(PearHole hole),并在其所有子类中提供具体实现。






























































猜你喜欢

转载自blog.csdn.net/someonemh/article/details/80591429