在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。

    【角色】

    • 抽象访问者(Visitor):主要是为了访问者的扩展。里面定义了一系列的visit方法(这个方法可以通过方法名来区分,也可以使用参数来重载),用来指定不同元素对象该访问者所需要对应的不同操作逻辑。一般就一个元素提供一个visit方法。
    • 具体访问者(ConcreteVisitor):实现抽象的访问逻辑。
    • 抽象元素(Element):定义一个accept方法,参数通常就是抽象访问者。
    • 具体元素(ConcreteElement):实现accept完成对一个元素访问想要做的操作。本质就是调用传递来的抽象访问者的方法(即调用visitor的visit方法)。这种机制也称为双重分派,这样利用参数重载的特性,我们可以不用修改任何代码,添加的访问者都可以这种方式进行传递调用(通过参数重载来调用对应的方法)。
    • 对象结构(ObjectStructure):用来存放元素对象的。并提供遍历内部元素的方法。可以使用组合模式来实现。也可以是一个简单的集合对象。

    【优点】

    • 各角色的职责相互隔离,符合单一职责原则。Visitor、Element 、ObjectStructure各司其责,职责清晰。
    • 扩展性好,添加新的访问者不需要修改原代码,对于访问者来说,符合开闭原则。

    【缺点】

    • 增加新的元素类很困难,需要在每一个访问者类中增加相应访问操作代码,这违背了开闭原则;
    • 可能破坏元素类的封装性,元素对象有时候必须暴露一些自己的内部操作和状态,否则无法供访问者访问。

      1. /**
      2. * 文件访问者(抽象访问者)
      3. */
      4. public interface Visitor {
      5. /**
      6. * 访问PDF文件
      7. * @param pdfFile
      8. */
      9. void visitPdf(ResourceFile pdfFile);
      10. /**
      11. * 访问Word文件
      12. * @param wordFile
      13. */
      14. void visitWord(ResourceFile wordFile);
      15. }
      1. /**
      2. * 压缩文件(具体访问者)
      3. */
      4. public class CompressVisitor implements Visitor {
      5. @Override
      6. public void visitPdf(ResourceFile pdfFile) {
      7. System.out.println("压缩PDF文件:" + pdfFile.fileName);
      8. }
      9. @Override
      10. public void visitWord(ResourceFile wordFile) {
      11. System.out.println("压缩Word文件:" + wordFile.fileName);
      12. }
      13. }
      /**
      * 解压缩文件(具体访问者)
      */
      public class ExtractVisitor implements Visitor {
      
        @Override
        public void visitPdf(ResourceFile pdfFile) {
            System.out.println("解压缩PDF文件:" + pdfFile.fileName);
        }
      
        @Override
        public void visitWord(ResourceFile wordFile) {
            System.out.println("解压缩Word文件:" + wordFile.fileName);
        }
      }
      
      /**
      * 抽象文件类(抽象元素)
      */
      public abstract class ResourceFile {
        /**
         * 文件名
         */
        protected String fileName;
      
        public ResourceFile(String fileName) {
            this.fileName = fileName;
        }
      
        /**
         * 接收访问者
         */
        public abstract void accept(Visitor visitor);
      }
      
      /**
      * PDF文件(具体元素)
      */
      public class PdfFile extends ResourceFile {
      
        public PdfFile(String fileName) {
            super(fileName);
        }
      
        @Override
        public void accept(Visitor visitor) {
            visitor.visitPdf(this);
        }
      }
      
      /**
      * Word文件(具体元素)
      */
      public class WordFile extends ResourceFile {
      
        public WordFile(String fileName) {
            super(fileName);
        }
      
        @Override
        public void accept(Visitor visitor) {
            visitor.visitWord(this);
        }
      }
      
      /**
      * 文件管理
      */
      public class FileManage {
      
        /**
         * 文件集合
         */
        List<ResourceFile> fileList = new ArrayList<>();
      
        /**
         * 添加文件
         */
        public void add(ResourceFile file) {
            fileList.add(file);
        }
      
        /**
         * 处理文件
         */
        public void process(Visitor visitor) {
            for (ResourceFile file : fileList) {
                file.accept(visitor);
            }
        }
      }
      

      ```java public class VisitorTest { public static void main(String[] args) {

        FileManage fileManage = new FileManage();
        fileManage.add(new PdfFile("访问者模式第1版.pdf"));
        fileManage.add(new PdfFile("访问者模式第2版.pdf"));
        fileManage.add(new WordFile("访问者模式.word"));
      
        // 压缩文件
        CompressVisitor compressVisitor = new CompressVisitor();
        fileManage.process(compressVisitor);
      
        System.out.println();
      
        // 解压缩文件
        ExtractVisitor extractVisitor = new ExtractVisitor();
        fileManage.process(extractVisitor);
      

      } } ——输出—— 压缩PDF文件:访问者模式第1版.pdf 压缩PDF文件:访问者模式第2版.pdf 压缩Word文件:访问者模式.word

    解压缩PDF文件:访问者模式第1版.pdf 解压缩PDF文件:访问者模式第2版.pdf 解压缩Word文件:访问者模式.word ```