Design Pattern: Visitor
Ph.D. Nguyen Hua Phung
Faculty of CSE, HCMUT
2007
Faculty of CSE,
HCMUT
Visitor design pattern 2
Motivation
•
Separate an algorithm from an object structure.
A tree structure
Task A
Task B
Task C
Faculty of CSE,
HCMUT
Visitor design pattern 3
Example
abstract class Expr { }
class BinExpr extends Expr {
Expr e1, e2;
char op;
}
class VarExpr extends Expr {
Token id;
}
class IntLiteral extends Expr {
Token lit;
}
(5 + b) * a
BinExpr
BinExpr VarExpr
*
IntLiteral VarExpr
+
5
b
a
e1 e2
e1 e2
lit id
id
Faculty of CSE,
HCMUT
Visitor design pattern 4
Task 1: Translate to postfix
•
Imperative programming
trans2post(Expr e) {
if (e instanceof BinExpr) {
BinExpr be = (BinExpr)e;
trans2post(be.e1);
trans2post(be.e2);
System.out.print(be.op);
} else if (e instanceof VarExpr) {
VarExpr ve = (VarExpr) e;
System.out.print(ve.id.Lexeme);
} else {
IntLiteral ie = (IntLiteral) e;
System.out.print(ie.lit.Lexeme);
}
}
BinExpr
BinExpr VarExpr
*
IntLiteral VarExpr
+
5
b
a
e1 e2
e1 e2
lit id
id
5 b + a *(5 + b) * a
Faculty of CSE,
HCMUT
Visitor design pattern 5
Task 1: Translate to postfix (cont’d)
•
Object-oriented programming
abstract class Expr {
abstract void trans2post();
}
class BinExpr extends Expr {
Expr e1,e2;
char op;
void trans2post() {
e1.trans2post();
e2.trans2post();
System.out.print(op);
}
}
class VarExpr extends Expr {
Token id;
void trans2post() {
System.out.print(
id.Lexeme);
}
}
class IntLiteral extends Expr {
Token lit;
void trans2post() {
System.out.print(
lit.Lexeme);
}
}
Faculty of CSE,
HCMUT
Visitor design pattern 6
Add New Task: Type checking
•
Object-oriented programming
abstract class Expr {
abstract void trans2post();
abstract void typechecking();
}
class BinExpr extends Expr {
Expr e1,e2;
char op;
void trans2post() {
}
void typechecking() {
}
}
need to modify code when
adding more tasks
Faculty of CSE,
HCMUT
Visitor design pattern 7
Design Pattern: Visitor
A
Task 1
Task 2
B
Task 1
Task 2
C
Task 1
Task 2
A
B C
Task 1 Task 2
Visitor
for A
for B
for C
for A
for B
for C
Faculty of CSE,
HCMUT
Visitor design pattern 8
Task 1: Translate to postfix (cont’d)
•
Visitor design pattern
abstract class Expr {
abstract void accept(Visitor v);
}
class BinExpr extends Expr {
Expr e1,e2;
char op;
void accept(Visitor v) {
v.visitBE(this);
}}
class VarExpr extends Expr {
Token id;
void accept(Visitor v) {
v.visitVE(this);
}}
abstract class Visitor {
abstract void visitBE(BinExpr e);
abstract void visitVE(VarExpr e);
abstract void visitIL(IntLiteral e);
}
class In2Pos extends Visitor {
void visitBE(BinExpr e) {
e.e1.accept(this);
e.e2.accept(this);
System.out.print(e.op);
}
void visitVE(VarExpr e) {
System.out.print(
e.id.Lexeme);
} }
Faculty of CSE,
HCMUT
Visitor design pattern 9
Task 1: Translate to postfix (cont’d)
class Application {
public static main() {
Expr e = ;
Visitor v = new
In2Pos();
e.accept(v);
BinExpr
BinExpr VarExpr
*
IntLiteral VarExpr
+
5
b
a
e1 e2
e1 e2
lit id
id
BinExpr.accept(v)
In2Pos.visitBE(BinExpr e)
e.e1.accept(v);
e.e2.accept(v);
System.out.print(op);
BinExpr.accept(v)
In2Pos.visitBE(BinExpr e)
e.e1.accept(v);
e.e2.accept(v);
System.out.print(op);
IntLiteral.accept(v)
In2Pos.visitIL(IntLiteral e)
VarExpr.accept(v)
In2Pos.visitVE(VarExpr e)
5 b + a *
Faculty of CSE,
HCMUT
Visitor design pattern 10
Add New Task: Type checking
abstract class Expr {
abstract void accept(Visitor v);
}
class BinExpr extends Expr {
Expr e1,e2;
char op;
void accept(Visitor v) {
v.visitBE(this);
}}
class VarExpr extends Expr {
Token id;
void accept(Visitor v) {
v.visitVE(this);
}}
abstract class Visitor {
abstract void visitBE(BinExpr e);
abstract void visitVE(VarExpr e);
abstract void visitIL(IntLiteral e);
class In2Pos extends Visitor { }
class TypeCheck extends Visitor {
void visit(BinExpr e) { }
void visit(VarExpr e) { }}
class Application {
public static main() {
Expr e = ;
Visitor v = new TypeCheck();
e.accept(v); // Type check
v = new In2Pos();
e.accept(v); // Translate to postfix
Faculty of CSE,
HCMUT
Visitor design pattern 11
Summary
•
Visitor design pattern is used to separate an algorithm
from a data structure.
•
It is used to implement many algorithms on the same
data.
•
Useful to implement type checker, code generation
•
Less useful at development stage when some new
classes might be added