访问者模式
定义
访问者模式是一个相对简单的模式。封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
英文定义:Represent an operation to be performed on the elements of an object structure .
访问者模式的UML类图如下所示:
访问者模式.jpg上图中涉及到的角色如下:
- 抽象访问者(Visitor):抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法的参数定义哪些对象可以被访问的。
- 具体访问者(ConcreteVisitor):它影响访问者访问到一个类后该怎么干,要做什么事情。
- 抽象元素(Element):接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。
- 结构对象(ObjectStruture):元素产生者,一般容纳在多个不同类不同接口的容器。
实例代码如下所示
//抽象元素
public abstract class Element{
//定义业务逻辑
public abstract void doSomething();
//允许谁来访问
public abstract void accept(IVisitor visitor);
}
//具体元素
public class ConcreteElement extends Element{
//完善业务逻辑
public void doSomething(){
//业务逻辑
}
//允许哪个访问者访问
public void accept(IVisitor visitor){
visitor.visit(this);
}
}
public class ConcreteElement2 extends Element{
//完善业务逻辑
public void doSomething(){
//业务逻辑
}
//允许哪个访问者访问
public void accept(IVisitor visitor){
visitor.visit(this);
}
}
//抽象访问者
public interface IVisitor{
//可以访问哪些对象
public void visit(ConcreteElement1 el1);
public void visit(ConcreteElement2 el2);
}
//具体访问者
public class Visitor implements IVisitor{
//访问el1元素
public void visit(ConcreteElement1 el1){
el1.doSomething();
}
//访问el2元素
public void visit(ConcreteElement2 el2){
el2.doSomething();
}
}
//结构对象
public class ObjectStruture{
//对象生成器,这里通过一个工厂方法模式模拟
public static Element createElement(){
Random rand = new Random();
if(rand.nextInt(100)>50){
return new ConcreteElement1();
}else{
return new ConcreteElement2();
}
}
}
//场景类
public class Client{
public static void main(String[] args){
for(int i=0;i<10;i++){
//获得元素对象
Element el = ObjectStruture.createElement();
//接受访问者访问
el.accept(new Visitor());
}
}
}
优缺点
优点:
- 符合单一职责原则
- 优秀的扩展性
- 灵活性非常高
缺点:
- 具体元素对访问者公布细节
- 具体元素变更比较困难
- 违背了依赖倒置原则
使用场景:
- 一个对象结构包含很多类对象,它们有不同的接口,而你相对这些对象实施一些依赖于其具体类的操作,也就是说用迭代器模式已经不能胜任的场景。
- 需要对一个结构中的对象进行很多不同并且不惜那关的操作,而你想避免让这些操作“污染”这些对象的类。
- 访问者模式是一种集中规整模式,特别适用于大规模重构的项目。
网友评论