Comp201: Principles of Object-Oriented Programming I
Spring 2008 -- Lab 7   


The Visitor Design Pattern

Introduction

This tutorial consists of exercises on the visitor pattern discussed in class.  It also helps prepare for HW06.  


I. To Drive or Not To Drive

Consider the following UML model of keys and cars:

You are to do the following:

1. Fill in the concrete methods of all the above concrete classes so that only a specific key will drive a specific car when that car's turnKey() method is called with that key, i.e. call its drive() method. All other keys will call the car's alarm() method. Download ACar.java and AKey.java.

For instance, suppose we have:

then ford.turnKey(fordKey) will cause ford.drive() to be called.

On the other hand, suppose instead we have

then ford.turnKey(saturnKey) will cause ford.alarm() to be called.

2. Fill in the ACar.drive() and ACar.alarm() methods to print out something indicative that the method has been called, e.g. "Car has been driven!" and "Car alarm sounded!".

3. Document your code, of course. It is recommended that you document the methods before you write the method bodies!

3. Write a test program that clearly tests all possible key and car combinations. Be sure that the test program prints clear messages indicating exactly what is being tested at the moment, i.e. what key-car combination is being used.


II. Student's Social Life

Create the object system that models the following using the Visitor Design pattern:

You're sitting in your room...um...."working"....or maybe not..... Suddenly, the phone rings and some person is on the other end. You need to proffer a response, but the exact response behavior will depend on not only what you've been doing, but who the person on the line is.

Now, there are a couple of scenarios:

  1. You've been working diligently on your Comp201 homework and the person calling is:
    1. Your mother. You want say "Oh yes, Mom, I've been working so hard, I haven't got time to even think about going to parties!"
    2. Your Comp201 lab-mate: You want to say "Problem 4's a piece of cake, once you understand double-dispatching!"
    3. Your significant other. You want to say "I'll be done in a minute!"
  2. You've been vegging out watching re-runs of the Gong Show and the person calling is:
    1. Your mother. You want say "Of course, I'm working hard! By the way, did I tell you that books cost more than I thought they would?!"
    2. Your Comp201 lab-mate. You want to say "Uh...do you have a clue how to do Problem 1?"
    3. Your significant other. You want to say "I'll be there right now!"

Some things to consider:

You are required to do the following:

  1. Create a UML diagram that models the above situation.
  2. Write a JUnit test class that clearly demonstrates that your system properly handles all 6 of the above scenarios. Be sure that the test code makes it obvious what scenario is being tested at the moment.
  3. Write all the code, including all the method bodies.
  4. Document all your code, of course.

III. List Visitor Exercises

You will need use the IList framework in the listFW package in order to compile and test your code. Download the listFW package with visitors here. Note that these problems are the start of HW06.

Assume that the IList contains Integer objects.

Since Integer objects and primitives like int contain no intelligence and cannot be inherited because they are final, we need an external technique to compare their values and then perform different tasks based on the result of the comparison. This can be accomplished using the if-else construct (see below).

BEFORE you start an exercise, write an appropriate JUnit test method (you can put them all into a single Test_ListVisitor test class) to test your expected results!

  1. Write a visitor called CheckAllNonNegative that checks to see if all elements in the host IList are non negative.  Its methods should return true if all the Integer elements in this IList are non-negative (>= 0), false otherwise. 
  2. Write a visitor called nonNegCount  that computes and returns the number of non-negative Integer elements in this IList.  Its methods should return an Integer.
  3. Write a visitor called checkMostlyNonNeg that checks to see if the host IList contains more non-negative integer than negative ones.  Its methods should return a Boolean
  4. Write a visitor called Sum to compute the sum of IList, assuming IList contains Integer objects.  Write one version using direct (reverser accumulation) recursion, and one version employing forward accumulation, called GetSum which uses a helper visitor called HelpGetSum

The "if-else" construct

Disclaimer

The conditional construct, "if-else", is a much abuse feature of most programming languages. We have not introduced it until now because we want you to understand that its use is very often unnecessary and perhaps worse, the product of poor design. Good object oriented programming has minimal use for conditional statements, relying instead on the intrinsic behavior already built into its objects. Delegation is a much more robust, flexible, extensible and proveably correct technique of generating varying behavior than conditional statements.

But there are times when it is useful, particularly when dealing with primitives, as they cannot be endowed with their own intelligence, so we plunge into dark and dangerous waters...

The if-else construct is used to choose between the execution of two sets of statements depending on a boolean value. That is, one set of statements is executed if the value is true and the other set is executed if the value is false. The general syntax for the if-else construct is


	if ( [boolean expression]) {

		[true statement 1]

		[true statement 2]

		[etc...]

	}

	else {

		[false statement 1]

		[false statement 2]

		[etc...]

	}

where[boolean expression] is an expression that evaluates to a boolean true or false value. If the[boolean expression] evaluates to true, then the [true statements] will be executed, otherwise the [false statements]will be executed.

For more information on the if-else construct, see the Java Resources page on if-else.

For example:


	if ( x > 5) {

		x = 0;

		System.out.println("x has been reset to zero.");

	}

	else {

		x++;

		System.out.println("x = "+x);		

	}

The result of this code would be:

for x = 3: "x = 4"

for x = 7: "x has been reset to zero"

To create expressions that result in boolean values, you can use the primitive comparison operators: > , <, >=, <=, ! (not) , != (not equal), == (equal), && (and), || (or) and ^ (exclusive or)

For more information on theses operators, see the Java Resources page on "Expressions".

Note that these are comparison operators whose expressions result in booleans, which is not the same as actually performing the boolean operation on the supplied values! In particular, "==" does not do an assignment, while "=" does! See the important advice at the bottom of the Java Resources page on if-else that may save you hours of debugging!

Shortcuts (not without their pitfalls!)

 

 


Last Revised Thursday, 03-Jun-2010 09:50:27 CDT

©2008 Stephen Wong and Dung Nguyen