|
Comp201: Principles of Object-Oriented Programming I
|
Check the time stamp at the bottom of the page to be sure that you have the latest version with any typographical corrections!
Pledge of Honor |
1.a 5 pts | 1.b 5 pts | 1.c 5 pts | 1.d 15 pts | 2.a10 pts | 2.b 15 pts | 3.a 15 pts | 3.b 10 pts | 3.c 15 pts | 3.d 5 pts | Total: 100 pts
|
Let's consider a model of a roommate. As we all know, roommates behave differently in different circumstances and how they behave can change almost instantaneously. Suppose we had a class that modeled a roommate.
We'll use a simplified representation of a roommate where the following features apply:
The test code below may thus be a reasonable approximation on how our roommate behaves during a sequence of actions:
Roommate rm = new Roommate(Color.BLUE);
assertEquals("Eye color", Color.BLUE, rm.getEyeColor());
assertEquals("Greeting, initial", "Zzzzzzz....", rm.getGreeting());
assertEquals("Greeting, second time after initial.", "Go away!", rm.getGreeting());
assertEquals("Greeting, third time after initial.", "Go away!", rm.getGreeting());
rm.study(1);
assertEquals("Greeting, after 1 hour study", "Go away!", rm.getGreeting());
rm.study(40);
assertEquals("Greeting, after 40 hours study", "Go away!", rm.getGreeting());
rm.eat();
assertEquals("Greeting, after eat.", "What a great day!", rm.getGreeting());
assertEquals("Eye color", Color.BLUE, rm.getEyeColor());
rm.eat();
assertEquals("Greeting, after eat again.", "Huh? Where am I?", rm.getGreeting());
rm.eat();
assertEquals("Greeting, after eat third time", "Zzzzzzz....", rm.getGreeting());
assertEquals("Greeting, again", "Go away!", rm.getGreeting());
rm.eat();
assertEquals("Greeting, after eat.", "What a great day!", rm.getGreeting());
rm.study(3);
assertEquals("Greeting, after 3 hours study.", "What a great day!", rm.getGreeting());
rm.study(4);
assertEquals("Greeting, after 4 hours study.", "Huh? Where am I?", rm.getGreeting());
assertEquals("Eye color", Color.BLUE, rm.getEyeColor());
From the above sequence interactions with a Roommate object, it is clear that the Roommate object changes its behavior dynamically. This dynamic change of behavior can be implemented using the state design pattern.
Problem 1.a: (5 pts) What depends on the state?
Of the methods of the Roommate class, getEyeColor(), eat(), getGreeting() and study(), which depend on the state of the roommate? Explain your reasoning.
Write your answers in the comments section of the Roommate.java file.
Problem 1.b: (5 pts) The States of a Roommate:
From the above test code, how many states do your think a Roommate has? Describe the states.
Write your answers in the comments section of the Roommate.java file.
Problem 1.c. (5 pts) Roommate's fields and abstract state: To start, start completing the code for Roommate.java as per the instructions below.
Problem 1.d (15 pts) Concrete States:
Implement the concrete states of Roommate using anonymous inner classes and initialize the current state of the Roommate, _state, to its proper value.
Suggestion: Before you start writing any code, on a piece of paper, using the information from the above test code, draw the state diagram of Roommate that shows the states of the system, the transitions from state to state and what methods cause those transitions.
Notes::
As was discussed in class, there Zipper code was supplied in Lab 11 created a pair of resultant lists that were the same because they shared the same internal states. Unfortunately, as we discovered, this caused undesirable effects, such as circular references, if one were to ever use those same lists together, such as zipping them together again.
The problem lies in the usage of the Share algorithm which causes creates the shared state between two lists. So what we want to do is to re-write the Zipper algorithm without using the Share visitor.
Your code must pass all the supplied test cases.
In a nutshell, the BetterZipper algorithm is:
Remember that in good OOP, your code should mirror the description of the problem. How does that idea relate the above algorithm to your code?
Notes:
In the last exam, we implemented a 3-way switch system. This system consisted of a couple of different types of switches and wires as well as a battery (which was really just a wire with a fixed voltage on it). But there were several problems with the code:
But we are now better armed with the notions of the State and Factory Design Patterns as well as anonymous inner classes. So let's improve out existing code to take advantage of our new knowledge.
Problem 3.a (15 pts): Anonymous States: First, we will need to fix the State Pattern implementation in the two 2-way switches.
Using the stub code that has been provided, fix the implementation of Two2OneSwitch by creating a new class BetterTwo2OneSwitch that has the following features:
Problem 3.b (10 pts): More Anonymous States: Under the same constraints as above, re-implement the State Design Pattern in One2TwoSwitch. Use the supplied stub code in the BetterOne2TwoSwitch class to complete your redesign. The test code is combined with that for the next section.
If you cannot get Problem 3.a to work properly, copy the State pattern code from One2TwoSwitch to BetterOne2TwoSwitch and leave this problem for after Problem 3.c!
Problem 3.c (15 pts): Wire Factories: To get rid of those annoying special wire classes, SwitchDownWire and SwitchUpWire, we re-examine the output of the One2TwoSwitch class. Comparing to the Two2OneSwitch class, we see that in that class, the switch's output appears as an IWire because the switch implements the IWire interface. That is, the output of the switch is actually a wire through which one can obtain a voltage, not just a bare voltage output. Turning back to One2TwoSwitch, we see that this is not the case here. One2TwoSwitch does not implement the IWire interface, so its output is two bare voltages, not wires.
Ah, but here's the rub: an IWire implementation is only capable of outputting a single voltage value, which works fine for Two2OneSwitch because it only has one wire coming out. But One2TwoSwitch has two different outputs, an "up" wire and a "down" wire that behave quite differently--that is, it appears to implement the IWire interface twice! How can a class effectively implement an interface twice and have different behaviors for those two implementations?
(Drum roll, please!) Factories to the rescue! We don't want two methods on One2TwoSwitch that give us voltages--we want two methods on One2TwoSwitch that give us wires. In effect, we want to have One2TwoSwitch factory those two specialized wires that are used to connect it to other electrical entities.
You are to re-design and re-write the getVoltageUp() and getVoltageDown() methods of One2TwoSwitch so they return IWires whose getVoltage() methods return the voltage from their respective wires. These methods are renamed getVoltageUpWire() and getVoltageDownWire() respectively in the supplied BetterOne2TwoSwitch stub code.
Be careful! Remember that the output voltage depends on the state of the switch!
Your code should pass all unit tests.
Problem 3.d (5 pts): Putting it all together into a better 3-way switch: In the constructor of the supplied class BetterThreeWaySwitch, insert coded modified from the constructor of ThreeWaySwitch to use the better two-way switch implementations. Your code should pass all unit tests.
Last Revised Thursday, 03-Jun-2010 09:50:25 CDT
©2008 Stephen Wong and Dung Nguyen