p.353,line.3-5: あるオブジェクト構造上の要素で実行されるオペレーションを表現する。 Visitorパターンにより、オペレーションを加えるオブジェクトのクラスに変更を加えずに新しいオペレーションを定義することができるようになる。

p.359,line.5-8: 6.カプセル化を破る。visitorによるアプローチでは、ConcreteElementクラスのインターフェイスが、visitorが仕事を行うのに十分、強力であることを仮定している。その結果、このパターンでは要素の内部状態にアクセスする公開オペレーションを提供するように強いられることがしばしばある。したがって、カプセル化に対して妥協を与えることになるかもしれない。
ConcreteElement クラスの公開オペレーションと内部状態へのアクセスオペレーションをそれぞれ仕様モジュールと実装モジュールに分離する。この対策は GoF パターンの場合でも別解の場合でも適用できる。
ConcreteElement の内部状態へのアクセス方法を、公開オペレーションとは分離できる。しかし、 ConcreteElement の追加、アルゴリズムの追加のいずれの場合も補完モジュールが必要になる。

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; ...
}
}
}
p.358 「3. 新しい ConcreteElement クラスを加えることは難しい」
p.336, line.4, 3.Adding new ConcreteElement classes is hard. The Visitor pattern makes it hard to add new subclasses of Element. Each new Concrete Element gives rise to a new abstract operation on Visitor and a corresponding implementation in every ConcreteVisitor Class.
MixJuice では、メソッド追加により Visitor パターンを後から導入できる。
また、MixJuice ではアブストラクトメソッド追加により、ConcreteElement クラスを加えることができる。

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) {...}
}
}
MixJuice では、Visitor パターンを使わなくても既存のモジュールを変更せずに新しいオペレーションを定義することができる。このように表現することにより、 Visitor パターンを使う場合と比較して Visitor クラスや accept メソッドが必要なくなり、クラス数・メソッド数が減少し、システムを単純化できる。
Visitor パターンを使う必要がなく、Visitor クラスが必要なくなり、記述を単純にできる
ただし、ConcreteVisitor クラスの定義において継承を利用する場合は、この方法は使えない。

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() {...} }
}