MTI TEK
  • Home
  • About
  • LLMs
  • Docker
  • Kubernetes
  • Java
  • All Resources
Java Design Patterns | Visitor
  1. Overview and Definition
  2. Class Diagram
  3. Implementation Example
    • The Visitor Interface
    • The Concrete Visitors
    • The Element Interface
    • The Concrete Elements
    • Testing the Visitor Pattern

  1. Overview and Definition
    The Visitor pattern is a behavioral design pattern that separates algorithms from the objects on which they operate. It allows adding new operations to existing object structures without modifying those structures. This is achieved by creating a visitor hierarchy that can traverse and operate on a family of related objects.

    Key Components:
    • Visitor: Declares visit methods for each type of concrete element in the object structure.
    • Concrete Visitor: Implements the operations defined in the Visitor interface for each type of element.
    • Element: Declares an accept method that takes a visitor as an argument.
    • Concrete Element: Implements the accept method which typically calls the visitor's visit method.

    Benefits:
    • Open/Closed Principle: New operations can be added without modifying existing element classes.
    • Single Responsibility: Related operations are gathered in one visitor class rather than scattered across multiple element classes.
    • Extensibility: New visitor types can be added easily to perform different operations on the same object structure.
  2. Class Diagram
    Visitor Pattern Components:
    • Visitor: ExtractionVisitor interface - defines visit methods for each concrete extractor type.
    • Concrete Visitors: TextExtractionVisitor and MetadataExtractionVisitor classes - implement different operations on extractors.
    • Element: TextExtractor interface - declares the accept method for visitor operations.
    • Concrete Elements: OCRExtractor and TikaExtractor classes - represent different document processing technologies.
    ┌──────────────────────────────────┐
    │       <<interface>>              │
    │     ExtractionVisitor            │  ← Visitor
    ├──────────────────────────────────┤
    │ + visitOCR(OCRExtractor): void   │
    │ + visitTika(TikaExtractor): void │
    └──────────────────────────────────┘
                 △
                 │ implements
                 │
    ┌───────────────────────┬─────────────────────────────┐
    │ TextExtractionVisitor │  MetadataExtractionVisitor  │  ← Concrete Visitors
    ├───────────────────────┼─────────────────────────────┤
    │+ visitOCR()           │+ visitOCR()                 │
    │+ visitTika()          │+ visitTika()                │
    └───────────────────────┴─────────────────────────────┘
    
    
    ┌───────────────────────────────────┐
    │           <<interface>>           │
    │           TextExtractor           │  ← Element
    ├───────────────────────────────────┤
    │ + accept(ExtractionVisitor): void │
    └───────────────────────────────────┘
                 △
                 │ implements
                 │
    ┌────────────────────────┬────────────────────────┐
    │   OCRExtractor         │  TikaExtractor         │  ← Concrete Elements
    ├────────────────────────┼────────────────────────┤
    │ - documentPath: String │ - documentPath: String │
    │ + accept()             │ + accept()             │
    │ + getDocumentPath()    │ + getDocumentPath()    │
    └────────────────────────┴────────────────────────┘
                   
  3. Implementation Example
    • The Visitor Interface:
      The Visitor interface declares visit methods for each type of concrete text extractor. Each visit method is specifically designed to work with a particular extractor technology.
      public interface ExtractionVisitor {
         void visitOCR(final OCRExtractor ocrExtractor);
         void visitTika(final TikaExtractor tikaExtractor);
      }
    • The Concrete Visitors:
      Concrete Visitors implement specific extraction operations that can be performed on different extractor types. Each visitor represents a different type of analysis or extraction that can be applied to documents.

      Text Extraction Visitor:
      public class TextExtractionVisitor implements ExtractionVisitor {
         public void visitOCR(final OCRExtractor ocrExtractor) {
             System.out.println("OCR Text Extraction from: " + ocrExtractor.getDocumentPath());
         }
      
         public void visitTika(final TikaExtractor tikaExtractor) {
             System.out.println("Tika Text Extraction from: " + tikaExtractor.getDocumentPath());
         }
      }
      Metadata Extraction Visitor:
      public class MetadataExtractionVisitor implements ExtractionVisitor {
         public void visitOCR(final OCRExtractor ocrExtractor) {
             System.out.println("OCR Metadata Extraction from: " + ocrExtractor.getDocumentPath());
         }
      
         public void visitTika(final TikaExtractor tikaExtractor) {
             System.out.println("Tika Metadata Extraction from: " + tikaExtractor.getDocumentPath());
         }
      }
    • The Element Interface:
      The Element interface declares the accept method that all concrete extractors must implement. This method allows visitors to perform different types of extraction operations.
      public interface TextExtractor {
         void accept(final ExtractionVisitor visitor);
      }
    • The Concrete Elements:
      Concrete Elements represent different document processing technologies and contain specific data. Each extractor calls the appropriate visit method on the visitor, passing itself as a parameter.

      OCR Extractor Element:
      public class OCRExtractor implements TextExtractor {
         private final String documentPath;
      
         public OCRExtractor(final String documentPath) {
             this.documentPath = documentPath;
         }
      
         public String getDocumentPath() {
             return documentPath;
         }
      
         public void accept(final ExtractionVisitor visitor) {
             visitor.visitOCR(this);
         }
      }
      Tika Extractor Element:
      public class TikaExtractor implements TextExtractor {
         private final String documentPath;
      
         public TikaExtractor(final String documentPath) {
             this.documentPath = documentPath;
         }
      
         public String getDocumentPath() {
             return documentPath;
         }
      
         public void accept(final ExtractionVisitor visitor) {
             visitor.visitTika(this);
         }
      }
    • Testing the Visitor Pattern:
      The client code demonstrates how different visitors can perform various extraction operations on the same document extractors. New extraction operations can be added by creating new visitor implementations without modifying existing extractor classes.
      public class VisitorPatternTest {
         public static void main(String[] args) {
             // Create text extractors
             TextExtractor ocrExtractor = new OCRExtractor("image.png");
             TextExtractor tikaExtractor = new TikaExtractor("document.docx");
      
             // Create visitors
             ExtractionVisitor textExtractor = new TextExtractionVisitor();
             ExtractionVisitor metadataExtractor = new MetadataExtractionVisitor();
      
             System.out.println("Text Extraction");
             ocrExtractor.accept(textExtractor);
             tikaExtractor.accept(textExtractor);
      
             System.out.println("Metadata Extraction");
             ocrExtractor.accept(metadataExtractor);
             tikaExtractor.accept(metadataExtractor);
         }
      }
© 2025 mtitek