The Visitor Pattern is used to separate an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying the structures themselves.
You have a Document class containing Paragraph and Image nodes. Now you want to add Export to PDF and Export to HTML. Instead of putting ToPdf() methods inside Paragraph and Image classes, you create a Visitor.
public interface IVisitor
{
void Visit(Paragraph p);
void Visit(Image i);
}
public class PdfVisitor : IVisitor { ... }
The Visitor pattern uses a technique called Double Dispatch: the element calls visitor.Visit(this). This allows the visitor to know the *exact runtime type* of the object it is dealing with, even when processing a generic list of base components.
Q: "Why is the Visitor pattern often criticized as an anti-pattern?"
Architect Answer: "Because it is **Inflexible for Data Changes**. If you add a new element type (e.g., `Table`), you MUST update the `IVisitor` interface and EVERY single concrete visitor class in the system. It breaks the Open/Closed Principle for data. You should ONLY use Visitor when your object structure is **Fixed** (rarely changes) but you expect to add many new **Operations** over time."