设计模式之访问者模式
访问者模式是一种分离对象数据结构与行为的方法,通过这种分离,可以为一个已存在的类或类群(即被访问者)增加新的操作(即访问者)而无需为它们作任何修改。访问者模式属于行为型模式。
为什么要使用访问者模式?
如何扩展一个现有的类层次结构来实现新行为?一般的方法是给类添加新的方法。但是万一新行为和现有对象模型不兼容怎么办?还有,类层次结构设计人员可能无法预知以后开发过程中将会需要哪些功能。以及,如果已有的类层次结构不允许修改代码,怎么能扩展行为呢?
答案是在类层次结构设计中使用访问者模式。
访问者模式涉及的角色:
1)访问者(Visitor)
访问者抽象接口,通过visit(Element)方法访问Element(数据结构),完成对Element的操作行为。
2)具体访问者(ConcreteVisitor)
访问者的具体实现类。
3)元素(Element),也就是被访问者
通过accept(Visitor)方法接受Visitor的访问。
4)具体元素(ConcreteElement)
元素的具体实现类。
5)对象结构(ObjectStructure)
拥有一组元素的组合对象。ObjectStructure本身也可以作为被访问者。
访问者模式的结构图(网上下载的):
当一个应用满足以下条件时,我们可以使用Visitor设计模式:
1)一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
2)需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Visitor使得你可以将相关的操作集中起来定义在一个类中。
3) 当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
4) 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。
优点:
1)易于添加那些目前尚未考虑到的方法。(这也是使用访问者的原因:扩展功能)
2)可以使类更加小巧,因为那些很少使用的方法,可以在外部定义。(意味着如果一个方法经常使用,最好定义在类中;当然在第一次定义中没有考虑到此方法除外)
缺点:
1)访问者角色不适合具体元素角色经常发生变化的情况。(如:增加新具体元素类,访问者接口就需要改变了。)
2)访问者角色要执行与元素角色相关的操作,就必须让元素角色将自己内部属性暴露出来,这就破坏了元素角色的封装性。访问者和被访问的对象的耦合性很大。
3)元素与访问者之间能够传递的信息有限,这往往也会限制访问者模式的使用。(因为访问者不能直接访问元素的私有数据)
示例: