ឥរិយាបថ កម្រិតស្មុគស្មាញ: ខ្ពស់

Visitor in Go

Add operations across a stable object structure without changing each node type whenever a new operation is introduced.

The Problem

Sometimes a structure is stable, but the operations over it keep growing. Reporting, export, auditing, and validation may all need to traverse the same catalog tree. If every new operation requires changing every node type, the structure becomes noisy and repetitive.

The Solution

Visitor moves each cross-cutting operation into a dedicated visitor object. In Go, nodes expose an Accept method and the visitor interface lists methods for each concrete node type. The tradeoff is explicitness: adding a new operation is easy, but adding a new node type requires updating the visitor contract.

Structure

  • Visitor interface: Declares visit methods for each node type.
  • Element interface: Nodes expose Accept.
  • Concrete elements: Category and product nodes delegate to the visitor.
  • Concrete visitor: PriceRollupVisitor accumulates totals across the tree.

Implementation

This example walks a small catalog tree and computes a price total without putting aggregation logic into every node type. The structure stays focused on domain data while the visitor carries the cross-cutting operation.

package main

type Visitor interface {
	VisitCategory(node CategoryNode)
	VisitProduct(node ProductNode)
}

type CatalogNode interface {
	Accept(visitor Visitor)
}

Best Practices

  • Use Visitor only when the node set is relatively stable and operations change more often.
  • Keep the visitor contract explicit so it is obvious which node types must be handled.
  • Pair Visitor with Composite when operations need to traverse a tree structure recursively.
  • Avoid Visitor when simple methods on the nodes would be clearer.
  • Be honest about the tradeoff: adding a new node type is more expensive with Visitor.

When to Use

  • A stable object structure needs many evolving cross-cutting operations.
  • You want to keep those operations out of the node types themselves.
  • Traversal should stay strongly typed rather than reflection-driven.

When NOT to Use

  • The structure changes frequently with new node types.
  • One or two simple methods on the nodes would be clearer.
  • The visitor ceremony would outweigh the benefit for a small model.