Download presentation
Presentation is loading. Please wait.
1
Zahra Moslehi AmirKabir University of Technology, Department of Computer Engineering & Information Technology Advanced design pattern Course Fall 2010 Design Pattern Course
2
I NTENT Allow an object to alter its behavior when its internal state changes Also known as: Objects for States
3
M OTIVATION The class TCPConnection delegates all state-specific requests to this state object TheTCPState class declares an interface common to all classes that represent different operational states the classes TCPEstablished and TCPClosed implement behavior particular to theEstablished and Closed states of TCPConnection
4
S TRUCTURE
5
A PPLICABILITY An object's behavior depends on its state An object must change its behavior at run-time depending on that state Operations have large, multipart conditional statements that depend on the object's state
6
P ARTICIPANTS Context (TCPConnection) maintains an instance of a ConcreteState subclass that defines the current state. clients don't have to deal with the State objects directly State (TCPState) defines an interface for encapsulating the behavior associated with a particular state of the Context. ConcreteState subclasses (TCPEstablished, TCPListen, TCPClosed) each subclass implements a behavior associated with a state of the Context.
7
C ONSEQUENCES Benefits Puts all behavior associated with a state into one object new states and transitions can be added easily by defining new subclasses State objects can be shared It makes state transitions explicit Helps avoid inconsistent states since state changes occur using just the one state object and not several objects or attributes It eliminates the necessity for a set of long, look-alike conditional statements scattered through the program’s code. in the process, simplifies and clarifies the program
8
C ONSEQUENCES ( CONT ) Liabilities Increased number of objects
9
I MPLEMENTATION How can the state object store its state elsewhere? Have the Context store this data and pass it to the state object (a push model) Have the Context store this data and have the state object retrieve it when needed ( a pull model)
10
Consider a simplified version of the Post Office Protocol used to download e-mail from a mail server Simple POP (SPOP) supports the following command: USER username The USER command with a username must be the first command issued PASS password The PASS command with a password or the QUIT command must come after USER. If the username and password are valid, then the user can use other commands. S AMPLE CODE (E XAMPLE 1)
11
LIST The LIST command returns the size of all messages in the mail box If the optional message number is specified, then it returns the size of that message. RETR The RETR command retrieves all message in the mail box If the optional message number is specified, then it retrieves that message. QUIT The QUIT command updates the mail box to reflect transactions taken, then logs the user out. S AMPLE CODE (E XAMPLE 1)
12
Here's a version of an SPop class without using the State pattern: public class SPop { static final int QUIT = 1; static final int HAVE_USER_NAME = 2; static final int START = 3; static final int AUTHORIZED = 4; private int state = START; String userName; String password; S AMPLE CODE (E XAMPLE 1)
13
public void user(String userName) { switch (state) { case START: { this.userName = userName; state = HAVE_USER_NAME; break; } default: { // Invalid command sendErrorMessageOrWhatEver(); endLastSessionWithoutUpdate(); userName = null; password = null; state = START; } S AMPLE CODE (E XAMPLE 1)
14
public void pass(String password) { switch (state) { case HAVE_USER_NAME: { this.password = password; if (validateUser()) state = AUTHORIZED; else { sendErrorMessageOrWhatEver(); userName = null; password = null; state = START; } default: { // Invalid command sendErrorMessageOrWhatEver(); endLastSessionWithoutUpdate(); state = START; }... S AMPLE CODE (E XAMPLE 1)
15
Now let's use the State pattern! S AMPLE CODE (E XAMPLE 1)
16
a push model public class SPopState { public SPopState user(String userName) {default action here} public SPopState pass(String password) {default action here} public SPopState list(int messageNumber) {default action here} public SPopState retr(int messageNumber) {default action here} public SPopState quit() {default action here} } public class Start extends SPopState { public SPopState user(String userName) { return new HaveUserName(userName); } S AMPLE CODE (E XAMPLE 1)
17
public class HaveUserName extends SPopState { String userName; public HaveUserName(String userName) { this.userName = userName; } public SPopState pass(String password) { if (validateUser(userName, password) return new Authorized(userName); else return new Start(); } S AMPLE CODE (E XAMPLE 1)
18
public class SPop { private SPopState state = new Start(); public void user(String userName) { state = state.user(userName); } public void pass(String password) { state = state.pass(password); } public void list(int messageNumber) { state = state.list(messageNumber); }... } S AMPLE CODE (E XAMPLE 1)
19
a pull model public class SPop { private SPopState state = new Start(); String userName; String password; public String getUserName() {return userName;} public String getPassword() {return password;} public void user(String newName) { this.userName = newName ; state.user(this); }... } S AMPLE CODE (E XAMPLE 1)
20
public class HaveUserName extends SPopState { public SPopState user(SPop mailServer) { String userName = mailServer.getUserName();... }... } S AMPLE CODE (E XAMPLE 1)
21
S AMPLE CODE (E XAMPLE 2)
22
S AMPLE CODE (E XAMPLE 3) S1 S2 a a/b b
23
class FSM { State state; public FSM(State s) { state = s; } public void move(char c) { state = state.move(c); } public boolean accept() { return state.accept();} } public interface State { State move(char c); boolean accept(); } S AMPLE CODE (E XAMPLE 3)
24
class State1 implements State { static State1 instance = new State1(); private State1() {} public State move (char c) { switch (c) { case 'a': return State2.instance; case 'b': return State1.instance; default: throw new IllegalArgumentException(); } public boolean accept() {return false;} } S AMPLE CODE (E XAMPLE 3)
25
class State2 implements State { static State2 instance = new State2(); private State2() {} public State move (char c) { switch (c) { case 'a': return State1.instance; case 'b': return State1.instance; default: throw new IllegalArgumentException(); } public boolean accept() {return true;} } S AMPLE CODE (E XAMPLE 3)
26
class AbstractTool is function moveTo(point) is input: the location point the mouse moved to (this function must be implemented by subclasses) function mouseDown(point) is input: the location point the mouse is at (this function must be implemented by subclasses) function mouseUp(point) is input: the location point the mouse is at (this function must be implemented by subclasses) S AMPLE CODE (E XAMPLE 4)
27
subclass PenTool of AbstractTool is last_mouse_position := invalid mouse_button := up function moveTo(point) is input: the location point the mouse moved to if mouse_button = down (draw a line from the last_mouse_position to point) last_mouse_position := point function mouseDown(point) is input: the location point the mouse is at mouse_button := down last_mouse_position := point function mouseUp(point) is input: the location point the mouse is at mouse_button := up S AMPLE CODE (E XAMPLE 4)
28
subclass SelectionTool of AbstractTool is selection_start := invalid mouse_button := up function moveTo(point) is input: the location point the mouse moved to if mouse_button = down (select the rectangle between selection_start and point) function mouseDown(point) is input: the location point the mouse is at mouse_button := down selection_start := point function mouseUp(point) is input: the location point the mouse is at mouse_button := up S AMPLE CODE (E XAMPLE 4)
29
class Cursor is current_tool := new PenTool function moveTo(point) is input: the location point the mouse moved to current_tool.moveTo(point) function mouseDown(point) is input: the location point the mouse is at current_tool.mouseDown(point) function mouseUp(point) is input: the location point the mouse is at current_tool.mouseUp(point) function usePenTool() is current_tool := new PenTool function useSelectionTool() is current_tool := new SelectionTool S AMPLE CODE (E XAMPLE 4)
30
R ELATED P ATTERNS Flyweight Singleton
31
Thanks for your attention؟
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.