一个实体,不同的访问者有不同的行为操作,而且访问者的种类也可能需要根据时间推移而变化(行为可扩展)
原则就是:软件的开闭原则:对修改关闭,对扩展开放
行为模式之一
Visitor
:为对象结构中具体元素角色声明一个访问操作接口Concrete Visitor
:实现每个由访问者接口声明的操作Element
:定义一个Accept
操作,它以一个访问者为参数Concrete Element
:实现Element定义的Accept
操作Object Structure
:具备特征:
这里以公园(元素)和清洁工(访问者)的关系来描述这个模式
/**
* element 元素的抽象
*/
public interface ParkElement {
public void accept(Visitor visitor);
}
/**
* 角色:具体访问元素
* 公园元素 公园包括A部分和B部分
*/
public class ParkConcreteElement implements ParkElement{
private ParkAConcreteElement parkA;
private ParkBConcreteElement parkB;
public ParkConcreteElement() {
this.parkA = new ParkAConcreteElement();
this.parkB = new ParkBConcreteElement();
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
parkA.accept(visitor);
parkB.accept(visitor);
}
}
/**
* 角色:具体访问元素
* 公园A部分
*/
public class ParkAConcreteElement implements ParkElement{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
/**
* 角色:具体访问元素
* 公园B部分
*/
public class ParkBConcreteElement implements ParkElement{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
/**
* 角色:访问者 Visitor
* 附加说明:这里定义了不同访问者有不同的visit方法
* 扩展上:这里也可以实现成策略模式,一个visit方法接受ParkElement,根据不同子类实现不同的visit具体实现
*/
public interface Visitor {
public void visit(ParkConcreteElement park);
public void visit(ParkAConcreteElement parkA);
public void visit(ParkBConcreteElement parkB);
}
/**
* 角色:具体访问者 公园管理者
**/
public class VisitorManager implements Visitor{
@Override
public void visit(ParkConcreteElement park) {
System.out.println("公园管理者视察Park");
}
@Override
public void visit(ParkAConcreteElement parkA) {
System.out.println("公园管理者视察ParkA");
}
@Override
public void visit(ParkBConcreteElement parkB) {
System.out.println("公园管理者视察ParkB");
}
}
/**
* 角色:具体访问者 清洁工A
**/
public class VisitorA implements Visitor{
@Override
public void visit(ParkConcreteElement park) {
}
@Override
public void visit(ParkAConcreteElement parkA) {
System.out.println("清洁工A清扫ParkA部分");
}
@Override
public void visit(ParkBConcreteElement parkB) {
}
}
/**
* 角色:具体访问者 清洁工B
**/
public class VisitorB implements Visitor{
@Override
public void visit(ParkConcreteElement park) {
}
@Override
public void visit(ParkAConcreteElement parkA) {
}
@Override
public void visit(ParkBConcreteElement parkB) {
System.out.println("清洁工B清扫ParkB部分");
}
}
/**
* 角色:访问元素构建
* - 能枚举他的元素
* - 可以提供一个高层的接口以允许该访问者访问他的元素
* - 可以是一个复合体或者一个集合
* 这里就简单创建一个单一的元素
*/
public class ObjectStructure {
private ParkElement park = new ParkConcreteElement();
public ParkElement getPark() {
return park;
}
public void setPark(ParkElement park) {
this.park = park;
}
}
/**
* Client 测试
*/
public class ClientTest {
public static void main(String[] args) {
// 通过对象结构获取访问元素(公园)
ObjectStructure objectStructure = new ObjectStructure();
ParkElement park = objectStructure.getPark();
// 访问者A来了(清洁工A来了)
VisitorA visitorA = new VisitorA();
park.accept(visitorA);
// 访问者B来了(清洁工B来了)
VisitorB visitorB = new VisitorB();
park.accept(visitorB);
// 访问者C来了(管理员来了)
VisitorManager visitorManager = new VisitorManager();
park.accept(visitorManager);
}
}