When designing systems with hierarchical relationships, I often encounter a problem that requires polymorphic behavior, but there is more than one type of work that benefits from this polymorphic implementation.
For example, consider a compiler that uses an abstract syntax tree to organize the source being analyzed for compilation. Itβs convenient to organize the logic polymorphically, since you can have more than one type of ValueProvider, each of which is responsible for throwing a different code to load the value into the operation stack. The problem is that you can also perform static analysis in AST, in which case you want to do a completely different job with the tree, but, nevertheless, it may have behavior that depends on the type of node being analyzed. In other words, you need polymorphic behavior, but you do not want to mix analysis code with compilation code.
The way I'm currently approaching this is to store data with an object model whose responsibility is simply to provide a tree. Each consumer of the tree (for example, a compiler or static analyzer) then uses runtime information to conditionally branch its logic. This inevitably leads to a large number of "if / else if" or "switch" encodings based on the node type. This is precisely this type of ugly branching that polymorphism is designed to solve, but a parallel, disjoint responsibility seems to require it.
Is there a better way to structure this?
Dan bryant
source share