|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
R - return typeA - argument typepublic interface NodeVisitor<R,A>
This interface implements part of the visitor pattern for nodes.
In object-oriented design a pattern has been established to let one class
react on the type of some object. Consider a tree composed of different types
of nodes all implementing a same base interface and some of them having
extensions of the interface. This is the situation for
Nodes for which several types exist.
The original idea was to attach the desired functionality to the nodes and
let it have one common method to invoke it. This turns out not to be
practical for modular components where the algorithm might be exchanged. This
is the case for the
DocumentWriter which
might produce Text, PDF, DVI, or some other output format. Any new
implementation of this interface would have the need to extend the Node
classes.
The other simplistic solution is to use a large switch, or cascaded if-then-else, to differentiate the cases. This kind of code is cumbersome to maintain. Whenever a new type of node is added you have to remember all places which need adaption.
This problem is solved in the visitor pattern. Each class or interface of the nodes has to provide one method called visit() here. This method has as one argument the visitor which should be called back. The visitor is defined by this interface. He has to provide a set of methods which allow him to differentiate the types of the nodes.
Each node has to implement the method visit() in a way that the appropriate method from the visitor interface is invoked. Thus as a result the nodes and the algorithm are decoupled.
The actions during the use of a NodeVisitor is illustrated in the following sequence diagram.
In this diagram a NodeVisitor is assumed to process two nodes. The first one
is a CharNode and the second
one is a GlueNode. We assume
that the concrete sub-type of Node to
be processed is not known. For instance it can be passed to the initial
method in a NodeList.
The first Node is processed by invoking the method visit(). The first argument is the reference to the current instanceof the NodeVisitor. Since the method is defined in CharNode to delegate it to the NodeVisitor by invoking the method visitChar(). Now the real work can be performed in the calling instance. Here the sub-type is known and can be taken into account.
After the return to the caller the second node can be taken into account. The procedure is the same: visit() is invoked. But now the delegation used the method visitGlue(). Thus in the calling instance the GlueNode can be processed specially.
Consider you have a class implementing DocumentWriter with a method which needs to react differently on different node types. The first approximation looks as follows:
public class MyDocumentWriter implements DocumentWriter {
public void myMethod(Node node) {
// Do something with node depending on its type
}
}
Now we can add the NodeVisitor interface. Thus we are forced to define a bunch of methods declared in this interface:
public class MyDocumentWriter
implements DocumentWriter,
NodeVisitor<Boolean, Integer> {
public void myMethod(Node node) {
// Do something with node depending on its type
}
public Boolean visitAdjust(AdjustNode node, Integer arg) {
// do something for adjust nodes
}
public Boolean visitChar(CharNode node, Integer arg) {
// do something for char nodes
}
// and many others..
}
Now we just have to make sure that those methods are invoked. This is done with the method visit() of the Node. The signature allows us to provide two additional arguments and receive a return value. Since we want to do something with the node itself, this node is provided with the correct type to the node visitor. The second argument can be casted to the appropriate type.
In the visit methods we can now safely assume that the node is of the named type and cast the object to have access to its public methods.
public class MyDocumentWriter
implements DocumentWriter,
NodeVisitor<Boolean, Integer> {
public void myMethod(Node node) {
node.visit(this, "some value");
}
public Object visitAdjust(AdjustNode node, Object arg) {
String s = (String) arg;
// do something for adjust nodes
}
public Object visitChar(CharNode node, Object arg) {
String s = (String) arg;
// do something for char nodes
}
// and many others..
}
In the example above we have not used the additional argument or the return value. In the visit methods we are free to use them in all ways we like.
The definition of the parameters and the return value are rather general. Thus it is possible to use the visitor pattern in several different situations.
The visitor is not necessarily the class MyDocumentWriter. If this class contains several methods which need to distinguish the types of the nodes it is possible to use another class as visitor, e.g. an inner class.
| Method Summary | |
|---|---|
R |
visitAdjust(AdjustNode node,
A value)
This method is called when an AdjustNode has been
encountered. |
R |
visitAfterMath(AfterMathNode node,
A value)
This method is called when an AfterMathNode has
been encountered. |
R |
visitAlignedLeaders(AlignedLeadersNode node,
A value)
This method is called when an AlignedLeadersNode
has been encountered. |
R |
visitBeforeMath(BeforeMathNode node,
A value)
This method is called when a BeforeMathNode has
been encountered. |
R |
visitCenteredLeaders(CenteredLeadersNode node,
A value)
This method is called when a CenteredLeadersNode
has been encountered. |
R |
visitChar(CharNode node,
A value)
This method is called when a CharNode has been
encountered. |
R |
visitDiscretionary(DiscretionaryNode node,
A value)
This method is called when a DiscretionaryNode
has been encountered. |
R |
visitExpandedLeaders(ExpandedLeadersNode node,
A value)
This method is called when an ExpandedLeadersNode
has been encountered. |
R |
visitGlue(GlueNode node,
A value)
This method is called when a GlueNode has been
encountered. |
R |
visitHorizontalList(HorizontalListNode node,
A value)
This method is called when a HorizontalListNode
has been encountered. |
R |
visitInsertion(InsertionNode node,
A value)
This method is called when an InsertionNode has
been encountered. |
R |
visitKern(KernNode node,
A value)
This method is called when a KernNode has been
encountered. |
R |
visitLigature(LigatureNode node,
A value)
This method is called when a LigatureNode has been
encountered. |
R |
visitMark(MarkNode node,
A value)
This method is called when a MarkNode has been
encountered. |
R |
visitPenalty(PenaltyNode node,
A value)
This method is called when a PenaltyNode has been
encountered. |
R |
visitRule(RuleNode node,
A value)
This method is called when a RuleNode has been
encountered. |
R |
visitSpace(SpaceNode node,
A value)
This method is called when a SpaceNode has been
encountered. |
R |
visitVerticalList(VerticalListNode node,
A value)
This method is called when a VerticalListNode
has been encountered. |
R |
visitVirtualChar(VirtualCharNode node,
A value)
This method is called when a VirtualCharNode
has been encountered. |
R |
visitWhatsIt(WhatsItNode node,
A value)
This method is called when a WhatsItNode has been
encountered. |
| Method Detail |
|---|
R visitAdjust(AdjustNode node,
A value)
throws GeneralException
AdjustNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitAfterMath(AfterMathNode node,
A value)
throws GeneralException
AfterMathNode has
been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitAlignedLeaders(AlignedLeadersNode node,
A value)
throws GeneralException
AlignedLeadersNode
has been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitBeforeMath(BeforeMathNode node,
A value)
throws GeneralException
BeforeMathNode has
been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitCenteredLeaders(CenteredLeadersNode node,
A value)
throws GeneralException
CenteredLeadersNode
has been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitChar(CharNode node,
A value)
throws GeneralException
CharNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitDiscretionary(DiscretionaryNode node,
A value)
throws GeneralException
DiscretionaryNode
has been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitExpandedLeaders(ExpandedLeadersNode node,
A value)
throws GeneralException
ExpandedLeadersNode
has been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitGlue(GlueNode node,
A value)
throws GeneralException
GlueNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitHorizontalList(HorizontalListNode node,
A value)
throws GeneralException
HorizontalListNode
has been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitInsertion(InsertionNode node,
A value)
throws GeneralException
InsertionNode has
been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitKern(KernNode node,
A value)
throws GeneralException
KernNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitLigature(LigatureNode node,
A value)
throws GeneralException
LigatureNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitMark(MarkNode node,
A value)
throws GeneralException
MarkNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitPenalty(PenaltyNode node,
A value)
throws GeneralException
PenaltyNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitRule(RuleNode node,
A value)
throws GeneralException
RuleNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitSpace(SpaceNode node,
A value)
throws GeneralException
SpaceNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitVerticalList(VerticalListNode node,
A value)
throws GeneralException
VerticalListNode
has been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitVirtualChar(VirtualCharNode node,
A value)
throws GeneralException
VirtualCharNode
has been encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
R visitWhatsIt(WhatsItNode node,
A value)
throws GeneralException
WhatsItNode has been
encountered.
node - the first parameter for the visitor is the node visitedvalue - the second parameter for the visitor
GeneralException - in case of an error
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||