美文网首页
访问者模式(visitor)

访问者模式(visitor)

作者: 剑道_7ffc | 来源:发表于2020-07-22 15:06 被阅读0次

一句话总结

访问者不同,结果不同

内容

不同访问者实现对相同数据集的不同的操作

场景

kpi考核:考核标准是相对稳定,但CEO和CTO的看重员工的点是不同的。
餐厅:餐厅的菜单和就餐方式是相对稳定的,但取就餐人员是每天变化的。

类图

image.png

代码示例

// 抽象元素
public interface IElement {
    void accept(IVisitor visitor);
}
// 具体元素
public class ConcreteElementA implements IElement {

    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public String operationA() {
        return this.getClass().getSimpleName();
    }
}
// 具体元素
public class ConcreteElementB implements IElement {

    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public int operationB() {
        return new Random().nextInt(100);
    }
}
// 结构对象
public class ObjectStructure {
    private List<IElement> list = new ArrayList<IElement>();

    {
        this.list.add(new ConcreteElementA());
        this.list.add(new ConcreteElementB());
    }

    public void accept(IVisitor visitor) {
        for (IElement element : this.list) {
            element.accept(visitor);
        }
    }
}
// 抽象访问者
public interface IVisitor {

    void visit(ConcreteElementA element);

    void visit(ConcreteElementB element);
}
// 具体访问者
public class ConcreteVisitorA implements IVisitor {

    public void visit(ConcreteElementA element) {
        String result = element.operationA();
        System.out.println("result from " + element.getClass().getSimpleName() + ": " + result);
    }
    public void visit(ConcreteElementB element) {
        int result = element.operationB();
        System.out.println("result from " + element.getClass().getSimpleName() + ": " + result);
    }
}
// 具体访问者
public class ConcreteVisitorB implements IVisitor {

    public void visit(ConcreteElementA element) {
        String result = element.operationA();
        System.out.println("result from " + element.getClass().getSimpleName() + ": " + result);
    }
    public void visit(ConcreteElementB element) {
        int result = element.operationB();
        System.out.println("result from " + element.getClass().getSimpleName() + ": " + result);
    }
}
public class Test {

    public static void main(String[] args) {
        ObjectStructure collection = new ObjectStructure();
        System.out.println("ConcreteVisitorA handle elements:");
        IVisitor visitorA = new ConcreteVisitorA();
        collection.accept(visitorA);

        System.out.println("------------------------------------");

        System.out.println("ConcreteVisitorB handle elements:");
        IVisitor visitorB = new ConcreteVisitorB();
        collection.accept(visitorB);
    }

}

运行结果


image.png

访问者模式中的两次动态分派

静态分派和动态分派

静态类型是List即变量的生命类型,实际类型是对象的类型

List str = new ArrayList()

静态分派指根据静态类型进行分派,在编译时期完成如重载方法的分配。
动态分派指根据实际类型进行分派,在运行时期完成如多态。

访问者模式中的两次动态分派

第一次分配

根据element的具体对象来决定调用具体元素对象的方法。

public void accept(IVisitor visitor) {
    for (IElement element : this.list) {
        element.accept(visitor);
    }
}
第二次分配

根据IVisitor的具体对象来确定调用哪个IVisitor具体实现方法。

public void accept(IVisitor visitor) {
    visitor.visit(this);
}

相关文章

网友评论

      本文标题:访问者模式(visitor)

      本文链接:https://www.haomeiwen.com/subject/mjnzkktx.html