訪問者模式表示一個作用於某對象結構中的各元素的操作,它使你可以在不改變各元素類的前提下定義作用於這些元素的新操作。
從定義可以看出結構對象是使用訪問者模式的必備條件,而且這個結構對象必須存在遍歷自身各個對象的方法,類似於Java中的Collection。
訪問者模式的目的是要把處理從數據結構中分離出來,如果系統有比較穩定的數據結構,又有易於變化的算法的話,使用訪問者模式是個不錯的選擇,因為訪問者模式使的算法操作的增加變得容易。相反,如果系統的數據結構不穩定,易於變化,則此系統就不適合使用訪問者模式了。
類圖:
訪問者模式結構:
訪問者角色(Visitor): 為該對象結構中具體元素角色聲明一個訪問操作接口.
具體訪問者角色(Concrete Visitor): 實現每個由訪問者角色(Visitor)聲明的操作.
元素角色(Element): 定義一個Accept操作,它以一個訪問者為參數.
具體元素角色(Concrete Element): 實現由元素角色提供的Accept操作.
對象結構角色(Object Structure): 這是使用訪問者模式必備的角色. 它要具備以下特征: 能枚舉它的元素; 可以提供一個高層的接口以允許該訪問者訪問它的元素; 可以是一個復合(組合模式)或是一個集合, 如一個列表或一個無序集合.
實例:
public interface Visitor
{
public void visit(GladiolusConcreteElement gladiolus);
public void visit(ChrysanthemumConreteElement chrysanthemum);
}
public interface FlowerElement
{
public void accept(Visitor visitor);
}
public class GladiolusConcreteElement implements FlowerElement
{
@Override
public void accept(final Visitor visitor)
{
visitor.visit(this);
}
}
public class ChrysanthemumConreteElement implements FlowerElement
{
@Override
public void accept(final Visitor visitor)
{
visitor.visit(this);
}
}
public class GladiolusVisitor implements Visitor
{
@Override
public void visit(final GladiolusConcreteElement gladiolus)
{
System.out.println(this.getClass().getSimpleName() + " access " + gladiolus.getClass().getSimpleName());
}
@Override
public void visit(final ChrysanthemumConreteElement chrysanthemum)
{
System.out.println(this.getClass().getSimpleName() + " access " + chrysanthemum.getClass().getSimpleName());
}
}
public class ChrysanthemumConreteElement implements FlowerElement
{
@Override
public void accept(final Visitor visitor)
{
visitor.visit(this);
}
}
public class ObjectStructure
{
private final List<FlowerElement> elements = new ArrayList<FlowerElement>();
public void addElement(final FlowerElement e)
{
elements.add(e);
}
public void removeElement(final FlowerElement e)
{
elements.remove(e);
}
public void accept(final Visitor visitor)
{
for (final FlowerElement e : elements)
{
e.accept(visitor);
}
}
}
public class Client
{
public static void main(final String[] args)
{
final ObjectStructure os = new ObjectStructure();
os.addElement(new GladiolusConcreteElement());
os.addElement(new ChrysanthemumConreteElement());
final GladiolusVisitor gVisitor = new GladiolusVisitor();
final ChrysanthemumVisitor chVisitor = new ChrysanthemumVisitor();
os.accept(gVisitor);
os.accept(chVisitor);
}
}
運行結果:
GladiolusVisitor access GladiolusConcreteElement
GladiolusVisitor access ChrysanthemumConreteElement
ChrysanthemumVisitor access GladiolusConcreteElement
ChrysanthemumVisitor access ChrysanthemumConreteElement