设计模式系列——访问者模式

134 阅读2分钟

原创:花括号MC(微信公众号:huakuohao-mc),欢迎分享,转载请保留出处。

访问者模式经常用于需要使用多种不同的方式去访问容器中的元素的场景。每个访问者有不同的访问策略。比如去医院看病的时候,我们拿着大夫开的药单子去划价处划价,财务人员看到的是所有药单的价格,当我们拿着同一份药单去药房拿药时,药房的工作人员关注的是具体的药品名称。同一份药单,不同的访问者,获取药单信息的内容是不一样的。

举个例子

定义一个计算机组件接口ComputerPart,该接口可以接受不同的访问者;然后分别定义KeyboardMouseMonitor等组件实现ComputerPart接口。

来看一下UML

visitor.png

在来看一下代码如何实现

先来定义一个ComputerPart接口,接受不同的访问者。

public interface ComputerPart {
    void accept(ComputerPartVisitor visitor);
}

定义Keyboard 实现ComputerPart接口

public class Monitor implements ComputerPart {
   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

定义一个Computer类实现ComputerPart接口

public class Computer implements ComputerPart {
    ComputerPart[] parts;

    public Computer() {
        parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};
    }

    @Override
    public void accept(ComputerPartVisitor visitor) {
        for (int i = 0; i < parts.length; i++){
            parts[i].accept(visitor);
        }
        visitor.visit(this);
    }
}

其他的Mouse Keyboard等类基本和Monitor类似,因为篇幅原因就不在列出。

来看一下访问者如何实现。

public class ComputerPartDisplayVisitor implements ComputerPartVisitor {
    //不同的部件有不同的访问策略
    @Override
    public void visit(Keyboard keyboard) {
        System.out.println("Displaying Keyboard.");
    }

    @Override
    public void visit(Monitor monitor) {
        System.out.println("Displaying Monitor.");
    }

    @Override
    public void visit(Mouse mouse) {
        System.out.println("Displaying Mouse.");
    }

    @Override
    public void visit(Computer computer) {
        System.out.println("Displaying Computer.");
    }
}

看一下客户端如何使用

public class VisitorPatternDemo {
    public static void main(String[] args){
        ComputerPart computer = new Computer();
        computer.accept(new ComputerPartDisplayVisitor());
    }
}

总结

访问者模式是行为模式之一,访问者模式的目的是要把处理从数据结构分离出来,当一个系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式比较合适,因为访问者模式使得算法操作的增加变得容易。

本文参考 www.tutorialspoint.com/design_patt…