| CSC 207 | Grinnell College | Fall, 2018 |
| Algorithms and Object-Oriented Design | ||
In this lab, you will get a concrete look at a brief motivating example of the state pattern, as described in Design Patterns Chapter 4.
Jerod Weinman wrote today's reading. Also, this lab is a lightly edited version of a lab, "State Pattern", written by Jerod Weinmen.
The state pattern is useful for modeling, well, the state of something. Namely, we need an easy way to switch the behavior of an object based on something we're calling "state."
For example, say we want to design a multilingual application. There will need to be all manner of messages that we'll need to print as output, and each of these translated in to the appropriate language. The particular message that's printed will depend on a language setting (the state).
The following code gives a short example using two message types in four different languages.
/** A class that prints out messages of various types in several
* languages.
*
* @author Jerod Weinman
*/
public class MultiLingualMessages {
/**
* An enumerated type explicitly listing the possible languages.
*/
public enum Language {English, French, Spanish, Chef};
/** Object member representing the language */
private Language lang;
/** Return the language of this object.
*
* @return the language of this object
*/
public Language getLanguage() { return lang; }
/** Set the language of this object. */
public void setLanguage(Language lang) {
this.lang = lang;
}
/** Print a question in the appropriate language */
public void printQuestion() {
String msg = "";
switch(lang) {
case English: msg = "What?"; break;
case Spanish: msg = "Que?"; break;
case French: msg = "Quoi?"; break;
case Chef: msg = "Bork?"; break;
default: throw new IllegalStateException("Unknown current language.");
}
System.out.println(msg);
}
/** Print an exclamation in the appropriate language */
public void printExclamation() {
String msg = "";
switch(lang) {
case English: msg = "Whoah!"; break;
case Spanish: msg = "¡Caramba!"; break;
case French: msg = "Par bleu!"; break;
case Chef: msg = "Bork!"; break;
default: throw new IllegalStateException("Unknown current language.");
}
System.out.println(msg);
}
}
Do you see why this is generally a painful design to work with?
Be prepared to discuss your answers as a class.
Let's see if we can begin to solve this problem. The state pattern we will use features the following elements:
We'll clarify what these mean in the next few exercises.
Messenger that has two
operations, one for fetching an exclamation String
and another for fetching the question String. (Note
that your return types should not
be void.)
FrenchMessenger
and ChefMessenger. You only need to write two,
one-line methods for each, and you need no object or class variables.
So what's this context thing all about? Well, this is where we finally
make use of the language messengers we pulled out above. Instead of
a enum Language variable representing our
state, as it does in MultiLingualMessages above, we can
use a Messenger object. Thus, the class below provides a
"context" for a particular messenger, replacing our original
class MultiLingalMessage.
/** A class that prints out messages of various types in several
* languages using the state pattern.
*
* @author Jerod Weinman
* @author YOUR NAME HERE
*/
public class MessengerContext
{
private Messenger messenger;
/**
* Set the messenger for this context to the specified value.
*
* @param msgr the specified value to use for this context.
*/
public void setMessenger(Messenger msgr)
{
messenger = msgr;
}
/** Print a question using the messenger state of this context. */
public void printQuestion()
{
// BODY HERE
}
/** Print an exclamation using the current messenger state of this context. */
public void printExclamation()
{
// BODY HERE
}
}
Messenger interface.
MultiLingualMessages?
Be prepared to discuss your answers as a class.
http://www.walker.cs.grinnell.edu/courses/207.sp012/labs/lab-state.shtml
|
created 6 January 2009 by Jerod Weinman revised 17 January 2011 by Jerod Weinman revised 18 February 2012 by Henry M. Walker |
|
| For more information, please contact Henry M. Walker at walker@cs.grinnell.edu. |