定义
访问者模式(Visitor Pattern)
定义:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作
Visitor抽象访问类:抽象类或接口,声明访问者可以访问那些元素
ConcreteVisitor具体访问类:影响访问到一个类该做什么
Element抽象元素:接口或抽象类,声明接受哪一类访问者访问
ConcreteElement具体元素:实现accept方法,通常是visitor.visit(this)
ObjectStruture结构对象:元素产生者,一般容纳在多个不同类的容器
通用源码
//抽象元素
public abstract class Element{
//定义业务逻辑
public abstract void doSomething();
//允许谁来访问
public abstract void accpet(IVisitor visitor);
}
//具体元素
public class ConcreteElement1 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 e1 = ObjectStruture.createElement();
//接受访问者访问
e1.accept(new Visitor());
}
}
}
应用
优点
- 符合单一职责原则:具体元素负责数据的加载;访问类负责报表的展现
- 优秀的扩展性:需要扩展直接在Visitor中增加方法即可
- 灵活性非常高
缺点
- 具体元素对访问类公开细节
- 具体元素变更很困难:具体元素的增删改都较困难
- 违背了依赖倒置原则:访问类依赖的是具体元素而不是抽象元素
使用场景
- 一个对象结构包含很多类对象,又有不同的接口,相对这些对象实施一些依赖于具体类的操作
- 需要对一个对象结构中的对象进行很多不同并且不相关的操作