1.访问者模式(Visitor Pattern):表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
2.类型:行为型模式
3.类图
4.各部分说明
抽象访问者:声明访问者可以访问哪些元素,具体到程序中就是visit方法中的参数定义哪些对象是可以被访问的。
访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情。
抽象元素类:声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。抽象元素一般有两类方法,一部分是本身的业务逻辑,另外就是允许接收哪类访问者来访问。
元素类:实现抽象元素类所声明的accept方法,通常都是visitor.visit(this),基本上已经形成一种定式了。
结构对象:一个元素的容器,一般包含一个容纳多个不同类、不同接口的容器,如List、Set、Map等。
5.实现
package 访问者模式;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class VisitorPattern {
public static void main(String[] args) {
List<Element> list = ObjectStruct.getList();
for (Element e:list) {
e.accept(new Visitor1());
}
}
}
//抽象元素类
abstract class Element{
public abstract void accept(Visitor visitor);
public abstract void doSomething();
}
//具体元素类
class ConcreteElement1 extends Element{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public void doSomething() {
System.out.println("元素1");
}
}
//具体元素类
class ConcreteElement2 extends Element{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public void doSomething() {
System.out.println("元素2");
}
}
//抽象访问者类
abstract class Visitor{
public abstract void visit(ConcreteElement1 element1);
public abstract void visit(ConcreteElement2 element2);
}
//具体访问者类
class Visitor1 extends Visitor{
@Override
public void visit(ConcreteElement1 element1) {
element1.doSomething();
}
@Override
public void visit(ConcreteElement2 element2) {
element2.doSomething();
}
}
//对象结构类
class ObjectStruct{
public static List<Element> getList(){
List<Element> list = new ArrayList<Element>();
Random ran = new Random();
for (int i = 0; i < 10; i++) {
int a = ran.nextInt(100);
if (a>50){
list.add(new ConcreteElement1());
}else{
list.add(new ConcreteElement2());
}
}
return list;
}
}
6.优点
部分遵守“开闭原则”。新增新的访问操作很方便,仅需要增加一个新的访问者即可在一个对象结构上定义一个新的操作。
对元素对象的访问方法集中到了一个访问者中而不是分散在各个元素中。
7.缺点
不完全遵守“开闭原则”。如果需要新增元素类,要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作。