cconnected.
Understand the pattern. Find your own way.Find your starting point
Your learning feed/Idea 179 of 218
Ideas this builds on
Low-level design179 / 218

Visitor: add operations over stable types

Picture

A tree contains numbers and additions. Evaluation and formatting are two different operations over those same elements.

Predict

Which change does Visitor make easier?

Walk through the small example

New operations over stable types. Visitor deliberately favors one direction of change.

Mental model and complete Python solution

Number and Add select the appropriate visitor operation through accept. Evaluator and Formatter each implement a complete operation over the same tree. This double-dispatch style separates operations from elements. Python pattern matching or singledispatch may be simpler in some codebases; the stable-type-set tradeoff still matters.

What the function promises: The finite expression tree contains Number and Add nodes. Evaluation returns a number; formatting returns parenthesized text.

class Number:
    def __init__(self, value):
        self.value = value
    def accept(self, visitor):
        return visitor.number(self)

class Add:
    def __init__(self, left, right):
        self.left, self.right = left, right
    def accept(self, visitor):
        return visitor.add(self)

class Evaluator:
    def number(self, node):
        return node.value
    def add(self, node):
        return node.left.accept(self) + node.right.accept(self)

class Formatter:
    def number(self, node):
        return str(node.value)
    def add(self, node):
        return f"({node.left.accept(self)} + {node.right.accept(self)})"

tree = Add(Number(2), Number(3))
assert tree.accept(Evaluator()) == 5
assert tree.accept(Formatter()) == "(2 + 3)"

Work and storage: O(tree size) evaluation; formatting can incur extra string-copying cost on deeply skewed trees.

When to recognize it: Adding an operation is convenient. Adding a new element type requires updating visitors that promise to handle every type.

Check before applying it: Frequent new element types can make Visitor expensive to maintain.

Change one rule

We add multiplication. What needs review?

See what changes

The new node’s dispatch and every visitor promising complete support. Unsupported cases should fail explicitly rather than silently producing incomplete output.

Connect

Composite: treat a tree uniformly: A composite supplies the tree of stable element types.

Template Method: fix the workflow: Compare a separate operation object with overridable workflow steps.