Should I avoid instanceof when working with a tree of objects?
-
26-09-2019 - |
Question
I have a class hierarchy representing different language constructs:
Expression <- NumericLiteral
UnaryExpression
BinaryExpression
IndexingExpression
IteratedExpression
...
The objects of these classes form complex tree hierarchies on which I have to perform various structural checks, e.g. if the node is an IteratedExpression then its first child should be an IndexingExpression. If the check only involves one level I can use the Visitor pattern, but in more complex cases as in the example below I am using instanceof.
void visit(IteratedExpression node) {
if (!(node.getChild(0) instanceof IndexingExpression)) {
// report error
}
}
Is it a proper use of instanceof or I have a flaw in my design? What are the alternatives?
Since there were some alternatives suggested I would like to emphasize the first part of the question:
Is it a proper use of instanceof or I have a flaw in my design?
Solution
Like this:
class Visitor {
boolean indexingExpected;
void startIteratedExpression() {
indexingExpected = true;
}
void doIndexing() {
indexingExpected = false;
}
void someOtherVisit() {
if (indexingExpected) {
throw IllegalStateException();
}
}
}
clas IteratedExpression {
private List<Expression> children;
public void visit(Visitor visitor) {
visitor.startIteratedExpression();
for(Expression child : childrenExpression) {
child.visit(visitor);
}
visitor.endIteratedExpression();
}
}
class IndexingExpression extends Expression {
public void visit(Visitor visit) {
visitor.doIndexing();
}
}
If you want use Visitor it doesn't matter how many levels you have in your tree.
OTHER TIPS
add an abstract method to Expression
and implement it in its children.
so each class will have its own checks.