访问者模式定义如下:
表示一个作用于某对象结构中的各个元素的操作。它可以在不改变各个元素的类的前提下,定义作用于这些元素的新操作。
适合访问者模式的情景如下:
想对集合中的对象增加一些新的操作;需要对集合中的对象进行很多不同且不相关的操作,而又不想修改对象的类。
问题的提出:
我们知道,人们认识事物常常有一个循序渐进的过程,不可能是一蹴而就的。例如,某事物经分析后有功能1、功能2、但是或者随着时间的推移,或者随着需求分析的变化,亦或者随着二次开发的需要,我们还必须要完成功能3。也许有些人想到可以用一个接口加上一个实现类来实现这种需求,当需要添加一个新的功能的时候,我们只需要在接口中定义新方法,然后在实现类中实现这个方法。但是有没有一种手段,在不修改接口及其实现类的基础上,实现新增的功能。
现在我想开发一个简单的计算机功能,假设我先实现了两位数加和减的功能,没有实现乘除,现在我想在原来设计的程序上添加功能:
1.原来的功能接口:
interface IComputer {
Integer add(int a, int b); //定义的加法
Integer subtract(int a, int b); //定义的减法
Object accept(IVisitor v); //可扩展的需求分析
}
2.原来接口实现类:
public class ComputerImpl implements IComputer {
int a, b;
public ComputerImpl(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public Integer add(int a, int b) {
return a + b;
}
@Override
public Integer subtract(int a, int b) {
return a - b;
}
@Override
public Object accept(IVisitor v) {
return v.visit(this);
}
}
这里的accept方法中的this相当于IVisitor的子类可以访问ComputerImpl类的成员变量
定义访问者接口IVisitor:
interface IVisitor {
Object visit(ComputerImpl com);
}
定义具体的新增的功能实现类
public class Multiply implements IVisitor {
@Override
public Object visit(ComputerImpl com) {
int sum = com.a * com.b;
return sum;
}
}
一个简单的测试类:
public class Test {
public static void main(String[] args) {
IVisitor v = new Multiply();
ComputerImpl c = new ComputerImpl(2, 3);
System.out.println(c.accept(v));
}
}
可知:如果我们在想增加一个求两个整数相除,只需在定义一个新类实现IVisitor接口,在该类中实现功能即可。