模式动机:
1、对于系统中的某些对象,它们存储在同一个集合中,且具有不同的类型,而且对于该集合中的对象,可以接受一类称为访问者的对象来访问,而且不同的访问者其访问方式有所不同,访问者模式为解决这类问题而诞生。
2、在实际使用时,对同一集合对象的操作并不是唯一的,对相同的元素对象可能存在多种不同的操作方式。
3、而且这些操作方式并不稳定,可能还需要增加新的操作,以满足新的业务需求。
4、此时,访问者模式就是一个值得考虑的解决方案。
5、访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式,这就是访问者模式的模式动机
模式意图:
访问者模式(Visitor Pattern):表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。访问者模式是一种对象行为型模式。
UML图:
角色:
Vistor: 抽象访问者为对象结构类中每一个抽象元素类声明一个访问操作。
ConcreteVisitor: 具体访问者具体访问者实现了每个由抽象访问者声明的操作,每一个操作用于访问对象结构中一种类型的元素。
Element: 抽象元素抽象元素一般是抽象类或者接口,它定义一个accept()方法,该方法以一个抽象访问者作为参数。
ConcreteElement: 具体元素实现了accept()方法,在其accept()中调用访问者的访问方法以便完成对一个元素的操作。
ObjectStructure: 对象结构是一个元素的集合,它用于存放元素对象,并且提供了遍历其内部元素的方法。
模式分析:
1、访问者模式中对象结构存储了不同类型的元素对象,以供不同访问者访问。
2、访问者模式包括两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,一个是元素层次结构,提供了抽象元素和具体元素。
3、相同的访问者可以以不同的方式访问不同的元素,相同的元素可以接受不同访问者以不同访问方式访问。在访问者模式中,增加新的访问者无须修改原有系统,系统具有较好的可扩展性。
代码:
public abstract class Visitor
{
public abstract void visit(ConcreteElementA elementA);
public abstract void visit(ConcreteElementB elementB);
}
public class ConcreteVisitor extendsVisitor
{
publicvoid visit(ConcreteElementA elementA)
{
//元素ConcreteElementA操作代码
}
publicvoid visit(ConcreteElementB elementB)
{
//元素ConcreteElementB操作代码
}
}
public interface Element
{
publicvoid accept(Visitor visitor);
}
public class ConcreteElementA implementsElement
{
publicvoid accept(Visitor visitor)
{
visitor.visit(this);
}
publicvoid operationA()
{
//业务方法
}
}
优缺点:
优点
1、使得增加新的访问操作变得很容易。
2、将有关元素对象的访问行为集中到一个访问者对象中,而不是分散到一个个的元素类中。
3、可以跨过类的等级结构访问属于不同的等级结构的元素类。
4、让用户能够在不修改现有类层次结构的情况下,定义该类层次结构的操作。
缺点:
1、增加新的元素类很困难。在访问者模式中,每增加一个新的元素类都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作,违背了“开闭原则”的要求。
2、破坏封装。访问者模式要求访问者对象访问并调用每一个元素对象的操作,这意味着元素对象有时候必须暴露一些自己的内部操作和内部状态,否则无法供访问者访问。
使用范围:
1、一个对象结构包含很多类型的对象,希望对这些对象实施一些依赖其具体类型的操作。在访问者中针对每一种具体的类型都提供了一个访问操作,不同类型的对象可以有不同的访问操作。
2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。访问者模式使得我们可以将相关的访问操作集中起来定义在访问者类中,对象结构可以被多个不同的访问者类所使用,将对象本身与对象的访问操作分离。
3、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
模式扩展:
1、由于访问者模式需要对对象结构进行操作,而对象结构本身是一个元素对象的集合,因此访问者模式经常需要与迭代器模式联用,在对象结构中使用迭代器来遍历元素对象。
2、在访问者模式中,元素对象可能存在容器对象和叶子对象,因此可以结合组合模式来进行设计。
倾斜的“开闭原则”
访问者模式以一种倾斜的方式支持“开闭原则”,增加新的访问者方便,但是增加新的元素很困难。