GOF对访问者模式的定义是:表示一个作用于某对象结构中各元素的操作,它使了可以在不改变各元素的类的前提下,定义作用于这些元素的新操作。基本代码如下
//抽象访问者
public abstract class Visitor {
public abstract void VisitConcreteElementA(ConcreteElementA A);
public abstract void VisitConcreteElementB(ConcreteElementB B);
}
//一个具体的访问者类
public class ConcreteVisitor extends Visitor {
@Override
public void VisitConcreteElementA(ConcreteElementA A) {
// TODO Auto-generated method stub
System.out.println(A.getClass().getCanonicalName()+"被"+this.getClass().getCanonicalName()+"访问");
}
@Override
public void VisitConcreteElementB(ConcreteElementB B) {
// TODO Auto-generated method stub
System.out.println(B.getClass().getCanonicalName()+"被"+this.getClass().getCanonicalName()+"访问");
}
}
//抽象元素类
public abstract class Element {
public abstract void accept(Visitor visitor);
}
//具体元素A
public class ConcreteElementA extends Element{
@Override
public void accept(Visitor visitor) {
// TODO Auto-generated method stub
visitor.VisitConcreteElementA(this);
}
public void operationA() {
}
}
//具体元素B
public class ConcreteElementB extends Element{
@Override
public void accept(Visitor visitor) {
// TODO Auto-generated method stub
visitor.VisitConcreteElementB(this);
}
public void operationB() {
}
}
//结构元素
public class ObjectStructure {
private List<Element> list_ele = new ArrayList<Element>();
public void attach(Element element) {
list_ele.add(element);
}
public void detach(Element element) {
list_ele.remove(element);
}
public void accept(Visitor visitor) {
for(Element ele : list_ele) {
ele.accept(visitor);
}
}
}
客户端代码
public class Client {
public static void main(String[] args) {
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.attach(new ConcreteElementA());
objectStructure.attach(new ConcreteElementB());
ConcreteVisitor concreteVisitor = new ConcreteVisitor();
objectStructure.accept(concreteVisitor);
}
}
运行截图
当我们希望开发的系统比较容易增加新操作的时候,可以考虑使用访问者模式,因为访问者模式可以让依赖于复杂对象结构的对象操作更简单,仅仅需要增加一个新的访问者就可以在一个数据结构上定义一个新的操作。如果不这样做,也就是当每个功能都分散在多个类中的话,定义新的操作时,就要去修改每一个类。
由于访问者集中了相关的操作且分离了无关的操作,所以互相相关的行为就不是分布在定义该对象结构的每个类上,而是集中在了一个访问者中,无关的行为则被分在各自访问者的子类当中,这样做简化了元素的类的同时也简化了在这些访问者所定义的算法,所有与之相关的数据结构都可以被隐藏在访问者中。
for Example,一个公司有几个不同的部门,A管理A部门,B管理B部门,CEO两者都管
package design.pattern.visitor.demo2;
import java.util.ArrayList;
import java.util.List;
//测试类
public class Test {
public static void main(String[] args) {
Visitor ceo = new CEO();
Visitor a = new A();
Visitor b = new B();
Corporation pa = new PartA();
Corporation pb = new PartB();
ObjectStructure os = new ObjectStructure();
os.addVisitor(pa);
os.addVisitor(pb);
os.accept(b);
os.accept(a);
os.accept(ceo);
}
}
//被访问节点
interface Corporation{
public void accept(Visitor v);
}
//A部门
class PartA implements Corporation{
String s = "PartA";
@Override
public void accept(Visitor v) {
// TODO Auto-generated method stub
v.visit(this);
}
public String getName() {
return s;
}
}
//B部门
class PartB implements Corporation{
String s = "PartB";
@Override
public void accept(Visitor v) {
// TODO Auto-generated method stub
v.visit(this);
}
public String getName() {
return s;
}
}
//访问者
interface Visitor{
public void visit(PartA A);
public void visit(PartB B);
}
//A管理A部门
class A implements Visitor{
@Override
public void visit(PartA A) {
System.out.println("A主管" + A.getName());
}
@Override
public void visit(PartB B) {
//
}
}
//B 管理B 部门
class B implements Visitor{
@Override
public void visit(PartA A) {
//
}
@Override
public void visit(PartB B) {
System.out.println("B主管" + B.getName());
}
}
//CEO管理两个部门
class CEO implements Visitor{
@Override
public void visit(PartA A) {
System.out.println("CEO主管" + A.getName());
}
@Override
public void visit(PartB B) {
System.out.println("CEO主管" + B.getName());
}
}
//提供一个高层接口以允许该访问者访问它的元素
class ObjectStructure{
public List<Corporation> eumn = new ArrayList<Corporation>();
public void addVisitor(Corporation e) {
eumn.add(e);
}
public void removeVisitor(Corporation corporation) {
eumn.remove(corporation);
}
public void accept(Visitor v) {
for(Corporation c : eumn)
c.accept(v);
}
}
运行结果如下
访问者模式可以在不改变某个层次结构中的类的情况下,为这个层次结构添加一个新的操作,访问者模式的机智主要包括为访问者制定一个接口,并将一个Accept方法加入到被调用的层次结构中去,利用两次分发的机制,访问者首先调用这个层次结构中的Accept方法,然后接收到调用的对象,将调用的结构通过Visit方法回复给访问者,Visit方法主要被定义在访问者中,并应该让被访问者所在层次结构中的某个对象去调用
以上内容,整理自刘径舟,张玉华编著的《设计模式其实很简单》读书笔记,欢迎转载