Represent operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Separation of specifications and implementations of ConcreteElement classes. (This improvement is applicable also to another solution described below.)

module element {
define abstract class Element {
define abstract void accept(Visitor visitor);
}
define class ConcreteElementA extends Element {
void accept(Visitor v){ v.visitConcreteElementA(this); }
}
define class ConcreteElementB extends Element {
void accept(Visitor v){ v.visitConcreteElementB(this); }
}
define abstract class Visitor {
define abstract void visitConcreteElementA(ConcreteElementA a);
define abstract void visitConcreteElementB(ConcreteElementB a);
}
}
module element.implementation extends element {
class ConcreteElementA {
int state;
}
class ConcreteElementB {
int state;
}
}
module visitor extends element {
define class ConcreteVisitor extends Visitor {}
}
module visitor.implementation
extends visitor, element.implementation {
class ConcreteVisitor {
void visitConcreteElementA(ConcreteElementA a){
... int x = a.state; ...
}
void visitConcreteElementB(ConcreteElementB b){
... int x = b.state; ...
}
}
}
Abstract method addition to Element and ConcreteElement classes solves the introductionability problem. Abstract method addition to Visitor and ConcreteVisitor classes solves the extensibility problem.

module element {
define abstract class Element {...}
define class ConcreteElementA extends Element {...}
define class ConcreteElementB extends Element {...}
}
module visitor extends element {
class Element { define abstract void accept(Visitor v); }
class ConcreteElementA { void accept(Visitor v) { v.visit(this); } }
class ConcreteElementB { void accept(Visitor v) { v.visit(this); } }
define class Visitor {
define abstract void visit(ConcreteElementA elt);
define abstract void visit(ConcreteElementB elt);
}
define class ConcreteVisitor1 extends Visitor {
void visit(ConcreteElementA elt) {...}
void visit(ConcreteElementB elt) {...}
}
define class ConcreteVisitor1a extends ConcreteVisitor1 {
void visit(ConcreteElementA elt) {...}
void visit(ConcreteElementB elt) {...}
}
}
module new_concrete_element extends visitor {
define class ConcreteElementC extends Element {
...
void accept(Visitor v) { v.visit(this); }
}
class Visitor {
define abstract void visit(ConcreteElementC elt);
}
class ConcreteVisitor1 {
void visit(ConcreteElementC elt) {...}
}
class ConcreteVisitor1a {
void visit(ConcreteElementC elt) {...}
}
}
Abstract method addition to the existing object structure.

module element {
define abstract class Element {...}
define class ConcreteElementA extends Element {...}
define class ConcreteElementB extends Element {...}
}
module traverser extends element {
class Element { define abstract void traverse(); }
class ConcreteElementA { void traverse() {...} }
class ConcreteElementB { void traverse() {...} }
}