作用于某个对象群中各个对象的操作。它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作。访问者模式的目的是要把处理从数据结构中分离出来,如果系统有比较稳定的数据结构,又有易于变化的算法的话,就方便使用访问者模式,如果数据结构不稳定,就不适合使用。
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof String){
System.out.println("'"+o.toString()+"'");
}else if (o instanceof Float){
System.out.println(o.toString()+"f");
}else{
System.out.println(o.toString());
}
}
访问者模式结构:
访问者角色(Visitor): 为该对象结构中每个具体元素角色声明一个访问操作接口。
具体访问者角色(Concrete Visitor): 实现每个由访问者角色(Visitor)声明的操作.
元素角色(Element): 定义一个Accept操作,它以一个访问者为参数,提供统一的访问接口。是所有可以被访问数据的父类。
具体元素角色(Concrete Element): 实现由元素角色提供的Accept操作。
对象结构角色(Object Structure): 这是使用访问者模式必备的角色。它要具备以下特征: 能枚举它的元素;
可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合, 如一个列表或一个无序集合。
/**
* 元素父类
*/
public interface Element {
//以一个访问者为参数
void accept(Visitor visitor);
}
StringElement 和FloatElement 两个具体的元素类型:
public class StringElement implements Element {
private String value;
public StringElement() {}
public StringElement(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void accept(Visitor visitor) {
visitor.visitString(this);
}
}
public class FloatElement implements Element {
private float value;
public float getValue() {
return value;
}
public void setValue(float value) {
this.value = value;
}
public FloatElement() {}
public FloatElement(float value) {
this.value = value;
}
public void accept(Visitor visitor) {
visitor.visitFloat(this);
}
}
访问者接口,为每一种数据类型提供了访问接口
/**
* 访问者接口,为每一种数据类型提供了访问接口
*/
public interface Visitor {
void visitString(StringElement stringElement);
void visitFloat(FloatElement floatElement);
}
/**
* 访问者实现
*/
public class ConcreteVisitor implements Visitor {
public void visitString(StringElement stringElement) {
System.out.println("String : "+ stringElement.getValue());
}
public void visitFloat(FloatElement floatElement) {
System.out.println("float : "+ floatElement.getValue());
}
}
下面是“对象结构角色(Object Structure)”
public class ObjectStructure {
private List<Element> elementList = new ArrayList<Element>();
public void add(Element element){
elementList.add(element);
}
public void accept(final Visitor visitor){
for (final Element e : elementList){
e.accept(visitor);
}
}
}
测试代码:
public static void main(String[] args) {
//创建对象结构
ObjectStructure os = new ObjectStructure();
FloatElement floatElement = new FloatElement(0.001f);
StringElement stringElement = new StringElement("string");
//对象结构添加数据,类似上面if..elseif结构中的数据集合
os.add(floatElement);
os.add(stringElement);
//访问数据
ConcreteVisitor visitor = new ConcreteVisitor();
os.accept(visitor);
}
对象结构角色(Object Structure) 是很重要,如果没有此角色,那么在测试代码中,就直接使用floatElement.accept(visitor); 那么和if..elseif 结构也没有什么区别了。
ObjectStructure 是一个数据结构,这样可以实现不同的数据结构,修改数据结构数据的访问不受影响。从而把数据结构和数据的访问分开。