visitor-访问模式

333 阅读1分钟

解决问题

采用“双重委派”方式,使访问者和被访问对象进行隔离。有点难理解。。。。

应用场景

它有一定的应用局限性,访问者和被访问者应该可被枚举,结构相对固定。比如说:运算符处理与数据结构的关系。(运算符+-*/可枚举,类型如String, int ,Object也是可以枚举的)

原理

示例

我们以处理运算表达式为例,来写个例子,只涉及+-,类型只涉及int,float, double。

public interface Element {
    public void accept(Visitor visitor);
}

@AllArgsConstructor
@Data
public class DoubleElement implements Element {
    private double left;
    private double right;

    @Override
    public void accept(Visitor visitor) {
       visitor.cal(this);
    }
}

@AllArgsConstructor
@Data
public class FloatElement implements Element {
    private int left;
    private int right;

    @Override
    public void accept(Visitor visitor) {
        visitor.cal(this);
    }
}
@AllArgsConstructor
@Data
public class IntElement implements Element {
    private int left;
    private int right;

    @Override
    public void accept(Visitor visitor) {
        visitor.cal(this);
    }
}
public interface Visitor {
    public void cal(DoubleElement element);

    public void cal(FloatElement element);

    public void cal(IntElement element);
}

public class MinusVisitor implements Visitor {
    public void cal(DoubleElement element) {
        System.out.print(element.getLeft()
        + "-"
        + element.getRight()
        + "="
        + (element.getLeft() - element.getRight()));
    }

    public void cal(FloatElement element) {
        System.out.print(element.getLeft()
                + "-"
                + element.getRight()
                + "="
                + (element.getLeft() + element.getRight()));
    }

    public void cal(IntElement element) {
        System.out.print(element.getLeft()
                + "-"
                + element.getRight()
                + "="
                + (element.getLeft() - element.getRight()));
    }
}
public class PlusVisitor implements Visitor {
    public void cal(DoubleElement element) {
        System.out.print(element.getLeft()
        + "+"
        + element.getRight()
        + "="
        + (element.getLeft() + element.getRight()));
    }

    public void cal(FloatElement element) {
        System.out.print(element.getLeft()
                + "+"
                + element.getRight()
                + "="
                + (element.getLeft() + element.getRight()));
    }

    public void cal(IntElement element) {
        System.out.print(element.getLeft()
                + "+"
                + element.getRight()
                + "="
                + (element.getLeft() + element.getRight()));
    }
}

public class Client {
    public static void main(String[] args) {
        DoubleElement doubleElement = new DoubleElement(10.21, 3.14);
        IntElement intElement = new IntElement(45, 21);
        PlusVisitor plusVisitor = new PlusVisitor();
        MinusVisitor minusVisitor = new MinusVisitor();

        doubleElement.accept(plusVisitor);
        intElement.accept(plusVisitor);
        intElement.accept(minusVisitor);
    }
}

参考

https://en.wikipedia.org/wiki/Visitor_pattern