Definition-Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
//UML Class Diagram
When to use?
• Suppose an object is always in one of several
known states
• The state an object is in determines the behavior
of several methods
• Could use if/case statements in each method
Compared to Strategy Pattern
Strategy Pattern typically configures context classes with a behavior or algorithm. But State Pattern allows a context to change its behavior as the state of the context changes.
Watch out: Using the State Pattern will typically result in a greater number of classes in your designed.
Notes
• Can use singletons for instances of each state class
– State objects don’t encapsulate state, so can be shared
• Easy to add new states
– New states can extend other states
• Override only selected functions
Example:
//Class Diagram
//Code
//Main.java
... {
TcpState tcpCurrentState;
TcpEstablishedState establishedState;
TcpListenState tcpListenState;
TcpClosedState tcpClosedState;
public TcpConnection()
...{
establishedState=new TcpEstablishedState(this);
tcpListenState=new TcpListenState(this);
tcpClosedState=new TcpClosedState(this);
tcpCurrentState=tcpClosedState;
}
public void Open()
...{
tcpCurrentState.Open();
}
public void Close()
...{
tcpCurrentState.Close();
}
public void Acknowledge()
...{
tcpCurrentState.Acknowledge();
}
public void SetState(TcpState tcpState)
...{
tcpCurrentState = tcpState;
}
public TcpState GetEstablishState()
...{
return this.establishedState;
}
public TcpState GetListenState()
...{
return this.tcpListenState;
}
public TcpState GetClosedState()
...{
return this.tcpClosedState;
}
}
interface TcpState ... {
void Open();
void Close();
void Acknowledge();
}
class TcpEstablishedState implements TcpState
... {
TcpConnection tcpConn;
public TcpEstablishedState(TcpConnection tcpConn)
...{
this.tcpConn = tcpConn;
}
public void Open()
...{
System.out.println("the connection has been established!");
}
public void Close()
...{
System.out.println("Closing...");
tcpConn.SetState(tcpConn.GetClosedState());
}
public void Acknowledge()
...{
System.out.println("acknowledge...and then listening ...");
tcpConn.SetState(tcpConn.GetListenState());
}
}
class TcpListenState implements TcpState
... {
TcpConnection tcpConn;
public TcpListenState(TcpConnection tcpConn)
...{
this.tcpConn = tcpConn;
}
public void Open()
...{
System.out.println("the connection has been established!");
}
public void Close()
...{
System.out.println("Closing...");
tcpConn.SetState(tcpConn.GetClosedState());
}
public void Acknowledge()
...{
System.out.println("acknowledge...continued listen...");
}
}
class TcpClosedState implements TcpState
... {
TcpConnection tcpConn;
public TcpClosedState(TcpConnection tcpConn)
...{
this.tcpConn = tcpConn;
}
public void Open()
...{
System.out.println("the connection is establishing...");
tcpConn.SetState(tcpConn.GetEstablishState());
}
public void Close()
...{
System.out.println("the connection has been Closed.Don't close again.");
}
public void Acknowledge()
...{
System.out.println("the connection has been Closed so that it could not acknowledge any msg");
}
}
public class Main ... {
public static void main(String[] args) ...{
// TODO Auto-generated method stub
TcpConnection tcpConn=new TcpConnection();
//right
tcpConn.Open();
tcpConn.Acknowledge();
tcpConn.Acknowledge();
tcpConn.Acknowledge();
tcpConn.Close();
//error
tcpConn.Close();
//right
tcpConn.Open();
tcpConn.Close();
}
}
//if u find anything interesting, pls contact with me.QQ:95491590