So far I have presented three different approaches to solving the expression problem, procedural, pure object-oriented, and a visitor pattern. This time I will present a technique I will refer to as layers. Like the visitor pattern, it is a modification of the pure object-oriented approach that takes advantage of partial classes. The solution begins very similarly to the other object-oriented approaches, I create an abstract class to represent an abstraction of expressions,
Notice the addition of the
partial modifier. I will
take advantage of that shortly. For now I will just flesh out the rest of the
hierarchy in a way that should, by now, be very familiar. I created a class to
Notice that, as with the pure object-oriented approach, I can keep the field used to hold the value as protected. This is also true for the class to represent an abstraction of binary operators.
The actual binary operators are just descendants of
BinaryOperator with no additional data.
So far, this is nearly identical to the pure object-oriented approach. Where
it differs is in how new operations are added. To add the
Evaluate() method, instead of modifying each class to add the methods, I can take advantage of the fact I left them
as partial classes and create additional parts that contain the methods instead.
First I created a new part of the
Expr class to
introduce the virtual method
Compiling now will generate several errors indicating that the other classes
do not implement the
Evaluate() method. This is
want I wanted. Using
abstract in the above class part lets the compiler help me
determine when I have completed the implementation of the evaluate operation.
The rest of the class parts for
Evaluate() looks like,
I call each of the collections of class parts a layer. You can think of them much like a transparency teachers uses on overhead projectors. You can build up a class by combining layers of functionality. I usually keep each layer in its own file named for the layer. In this case, Evaluator.cs might be a good choice.
To demonstrate building up a class with through layers I will create a printing layer.
As in the other approaches, I will demonstrate how to add support for the Power expression form. I have two choices, I can add it just as we did in the pure object-oriented approach,
or I could divide it into multiple parts that can be co-located with the other similar parts. The data part would look like,
The part for the expression layer would look like,
An the printing layer part would look like,
It is this flexibility that makes layers so appealing. You can decide, case by case, which is the right way to modify the hierarchy.