During this lab session:
This activity helps the student develop the following skills, values and attitudes: ability to analyze and synthesize, capacity for identifying and solving problems, and efficient use of computer systems.
This lab can be developed individually or in pairs.
Make a new folder called visitor
. Place all the files you
create in this folder.
What follows is one possible generic implementation of the Visitor Pattern using C#. This example basically allows representing trees of arithmetic expressions, similar to those seen in our previous class when we discussed the Interpreter Pattern.
namespace VisitorPattern { public interface IVisitor<T> { T Visit(Number<T> node); T Visit(Plus<T> node); T Visit(Times<T> node); } public interface INode<T> { T Accept(IVisitor<T> visitor); } public class Number<T>: INode<T> { public int Value { get; private set; } public Number(int value) { Value = value; } public T Accept(IVisitor<T> visitor) { return visitor.Visit(this); } } public abstract class BinaryOperator<T>: INode<T> { public INode<T> Left { get; private set; } public INode<T> Right { get; private set; } public BinaryOperator(INode<T> left, INode<T> right) { Left = left; Right = right; } public abstract T Accept(IVisitor<T> visitor); } public class Plus<T>: BinaryOperator<T> { public Plus(INode<T> left, INode<T> right): base(left, right) {} public override T Accept(IVisitor<T> visitor) { return visitor.Visit(this); } } public class Times<T>: BinaryOperator<T> { public Times(INode<T> left, INode<T> right): base(left, right) {} public override T Accept(IVisitor<T> visitor) { return visitor.Visit(this); } } }
A specific visitor can now be implemented like this:
namespace VisitorPattern { public class Eval: IVisitor<int> { public int Visit(Number<int> node) { return node.Value; } public int Visit(Plus<int> node) { return node.Left.Accept(this) + node.Right.Accept(this); } public int Visit(Times<int> node) { return node.Left.Accept(this) * node.Right.Accept(this); } } }
Extend the given code in the following ways:
Less<T>
(the
binary "less than" operator, that returns 1 when true, or 0
when false) and Condition<T>
(a ternary
conditional operator).
InOrder
and
PreOrder
. Check the unit tests in order to
understand how these classes should work.
Make sure the code that you write behaves exactly as expected by the following unit tests:
namespace VisitorPattern { using NUnit.Framework; [TestFixture] public class TestVisitor { INode<int> intRoot; INode<string> strRoot; [SetUp] public void Init() { // if 2 + 2 < 2 * 2 then 2 + 3 * 4 else (2 + 3) * 4 intRoot = new Condition<int>( new Less<int>( new Plus<int>( new Number<int>(2), new Number<int>(2)), new Times<int>( new Number<int>(2), new Number<int>(2))), new Plus<int>( new Number<int>(2), new Times<int>( new Number<int>(3), new Number<int>(4))), new Times<int>( new Plus<int>( new Number<int>(2), new Number<int>(3)), new Number<int>(4))); strRoot = new Condition<string>( new Less<string>( new Plus<string>( new Number<string>(2), new Number<string>(2)), new Times<string>( new Number<string>(2), new Number<string>(2))), new Plus<string>( new Number<string>(2), new Times<string>( new Number<string>(3), new Number<string>(4))), new Times<string>( new Plus<string>( new Number<string>(2), new Number<string>(3)), new Number<string>(4))); } [Test] public void TestEval() { Assert.AreEqual(20, intRoot.Accept(new Eval())); } [Test] public void TestInOrder() { Assert.AreEqual( "(((2 + 2) < (2 * 2)) ? (2 + (3 * 4)) : ((2 + 3) * 4))", strRoot.Accept(new InOrder())); } [Test] public void TestPreOrder() { Assert.AreEqual( "(if (< (+ 2 2) (* 2 2)) (+ 2 (* 3 4)) (* (+ 2 3) 4))", strRoot.Accept(new PreOrder())); } } }
To hand in your lab work, follow these instructions:
readme.txt
text file that includes the name
and student ID of the authors. Copy this file to the
visitor
folder.
visitor
directory. Call this file
visitor.zip
.
This activity will be evaluated using the following criteria:
100 | The code works as requested. |
---|---|
60-90 | The code works, but has some flaws. |
20-50 | The code doesn't work, but it seams that some amount of time was spent on it. |
DA | The program was plagiarized. |