Expression Tree Evaluator
Usage:
To run the program at the command line type:
java TreeProg
This will display a few trees that were pre-coded.
Basic Organization:
Trees are made up of nodes. These trees are predefined in the TreeProg class. The Iterator allows moving through tree in specific orders, depending on the type of Iterator defined.
Classes:
The following is a listing of the classes used in the program:
Node – A generic object in a specific location
TreeNode – A node in a tree
Int_Node – A node that holds a single integer
Unary_Node – A node that holds one operator and a tree
Binary_Node – A node that holds one operator and two trees
Ternary_Node – A node that holds one operator and three trees
Iterator – Class for iterating through a tree
PreIterator – Moves through the tree by printing in “pre-order” (current, left child, right child)
Tree – Structure that contains nodes
TreeProg – The main program
Patterns used:
Adapter
Convert the interface of a class into another interface that clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. By implementing the toString() method we are able to use the standard System.out.print(Object) method for printing.
Bridge
Decouple an abstraction from its implementation so that the two can vary independently. We created a print() method in Tree that called the abstract print() method in the Node class, and therefore the concrete print() method in the resulting nodes. This allowed us to keep the print() method in Tree while we could vary the implementation in the nodes.
Factory
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. The Tree class has multiple constructors that are called based on what type of data is passed to it. The Tree also implements a createIterator(String) method that creates a given iterator for that tree.
Façade
Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. By implementing the print() method for trees, we hide the complexity of printing each individual node in order.
Iterator
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. An Iterator was created to display the objects in a tree in a given order. The PreIterator class visits the nodes in the tree in pre-order. This is the pattern that was chosen to extend the original C++ implementation.
Java “Tricks”:
Because we implemented the toString() method for each of the TreeNodes we are able to change the print() method to used the standard System.out.print(String) method. This allows us to move the print() method to the Node class rather than specific implementations in the children.
Observations:
Rather than creating multiple types of nodes it would be easier to create an n-ary node that allowed for multiple sub-trees related to a given operator. This modification was not implemented.