Java Reference
In-Depth Information
To illustrate, let's take a tree structure that you'd like to traverse. Consider a simple arithmetic
language consisting of numbers and binary operations:
class Expr { ... }
class Number extends Expr { int val; ... }
class BinOp extends Expr { String opname; Expr left, right; ... }
Say you're asked to write a method to simplify some expressions. For example, 5 + 0 can be
simplified to 5. Using our domain, new BinOp("+", new Number(5), new Number(0)) could be
simplified to Number(5). You might traverse an Expr structure as follows:
Expr simplifyExpression(Expr expr) {
if (expr instanceof BinOp
&& ((BinOp)expr).opname.equals("+"))
&& ((BinOp)expr).right instanceof Number
&& ... // it's all getting very clumsy
&& ... ) {
return (Binop)expr.left;
}
...
}
You can see that this rapidly gets very ugly!
14.4.1. Visitor design pattern
Another way to unwrap the data type in Java is to make use of the visitor design pattern . In
essence, you can create a separate class that encapsulates an algorithm to “visit” a specific data
type.
How does it work? The visitor class needs to take as input a specific instance of the data type. It
can then access all its members. Here's an example of how this works. First, you add the method
accept to BinOp, which takes SimplifyExprVisitor as argument and passes itself to it (you also
add a similar method for Number):
class BinOp extends Expr{
...
public Expr accept(SimplifyExprVisitor v){
return v.visit(this);
}
 
Search WWH ::




Custom Search