ivaneye.com

语言与模式-22访问者模式

意图

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

适用性

Java实现

//访问者
public interface Visitor {
    public void visit(Park park);
    public void visit(ParkA parkA);
    public void visit(ParkB parkB);
}
//清洁工A,负责parkA的卫生情况
public class VisitorA implements Visitor {
    public void visit(Park park) {
    }
    public void visit(ParkA parkA) {
        System.out.println("清洁工A:完成公园" + parkA.getName()+ "的卫生");
    }
    public void visit(ParkB parkB) {
    }
}
//清洁工B,负责公园B部分的卫生
public class VisitorB implements Visitor {
    public void visit(Park park) {
    }
    public void visit(ParkA parkA) {
    }
    public void visit(ParkB parkB) {
        System.out.println("清洁工B:完成公园" + parkB.getName()+"的卫生");
    }
}
public class VisitorManager implements Visitor {
    public void visit(Park park) {
        System.out.println("管理员:负责" + park.getName() + "卫生检查");
    }
    public void visit(ParkA parkA) {
        System.out.println("管理员:负责公园"+ parkA.getName() +"部分卫生检查");
    }
    public void visit(ParkB parkB) {
        System.out.println("管理员:负责公园"+ parkB.getName() +"分部卫生检查");
    }
}
//公园每一部分的抽象
public interface ParkElement {
    //用来接纳访问者
    public void accept(Visitor visitor);
}
public class Park implements ParkElement {
    private String name;
    private ParkA parkA;
    private ParkB parkB;
    public Park() {
        this.parkA = new ParkA();
        this.parkB = new ParkB();
        parkA.setName("A");
        parkB.setName("B");
    }
    public void accept(Visitor visitor) {
        visitor.visit(this);
        parkA.accept(visitor);
        parkB.accept(visitor);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
//公园的A部分
public class ParkA implements ParkElement {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
//公园的B部分
public class ParkB implements ParkElement{
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
public class MainClass {
    public static void main(String[] args) {
        Park park = new Park();
        park.setName("锦绣公园");
        VisitorA visitorA = new VisitorA();
        park.accept(visitorA);
        VisitorB visitorB = new VisitorB();
        park.accept(visitorB);
        VisitorManager visitorManager = new VisitorManager();
        park.accept(visitorManager);
    }
}

Clojure实现

访问者模式干了什么呢?我自己(这里是Park)有个结构,我委托给其他对象(Visitor)来实现访问逻辑!

Clojure没有类似的结构体!比如复杂的树结构,可以使用Clojure提供的数据操作函数来进行操作即可!没必要实现个模式!