1.意图
允许一个对象在其内部状态改变的时候改变它的行为,对象看起来好像修改了它的类。
2.别名
状态对象(Objects for States).
最具有典型的状态模式的例子是TCP连接模型了。考虑一个表示网络连接的类TCPConnection。一个TCPConnection对象的状态处于若干不同状态之一:连接已经建立(Established)、正在监听(Listening)、连接已经关闭(Closed)。当一个TCPConnection对象收到其它对象的请求时,它根据自身的当前状态作出不同的反应。例如,一个Open请求的结果依赖于该连接是处于连接已经关闭状态还是连接已经建立状态。State模式描述了TCPConnection如何在每一种状态下表现出不同的行为。
引入状态模式的关键是抽象一个名称TCPState的接口出来,再分别建立TCPListen类,TCPEstablished类,TCPClose类来实现该接口,分别来表示TCPConnection对象在不同状态下的不同行为。
当然这里的TCPConnection类需要维持一个TCPState接口的实例,通过不同的状态来改变该接口的实例实现将TCPConnection的不同操作委托给TCPState的子类来完成。
5.Java代码实现
TCPState类参考实现:
public interface TCPState
{
void open();
void close();
void acknowIedge();
}
TCPClosed类的参考实现:
public class TCPClosed implements TCPState
{
public void acknowIedge()
{
// TODO Auto-generated method stub
}
public void close()
{
// TODO Auto-generated method stub
}
public void open()
{
// TODO Auto-generated method stub
}
}
TCPListen类的实现:
public class TCPListen implements TCPState
{
public void acknowIedge()
{
// TODO Auto-generated method stub
}
public void close()
{
// TODO Auto-generated method stub
}
public void open()
{
// TODO Auto-generated method stub
}
}
TCPEstablished类的实现:
public class TCPEstablished implements TCPState
{
public void acknowIedge()
{
// TODO Auto-generated method stub
}
public void close()
{
// TODO Auto-generated method stub
}
public void open()
{
// TODO Auto-generated method stub
}
}
TCPConnection类的参考实现:
public class TCPConnection
{
private TCPState state;
public void acknowIedge()
{
state.acknowIedge();
}
public void close()
{
state.close();
}
public void open()
{
state.open();
}
public void setState(TCPState state)
{
this.state = state;
}
}
6.何时使用状态模式
(1)一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
(2)一个操作中含有庞大的多分支的条件语句,并且这些分支依赖于该对象的状态,这些状态通常用一个或者多个枚举常量来表示。通常有多个操作包含这一相同的条件结构,State模式将每一个条件分支放入一个对立的类中。这使你可以根据对象自身的情况将对象的状态作为一个对象,这一个对象可以不依赖于其它对象而独立变化。
7.状态模式与策略模式的异同点
在类的结构模式上来讲,状态模式与策略模式的类图基本上一致。区别在于功能上的,并且还有如下几个细小但是关键差异。
状态模式的中TCPConnection类会根据自身的状态的不同将它的操作委托给对应状态的TCPState的子类,这个子类是在运行时动态改变的,但是对于策略模式来讲,选定了一种子策略之后,就不会变了,一直到用完为止。也就是说状态模式的状态是变化的,但是策略模式的策略只要是选定了就不会变化。
策略模式的环境类自己来选择采用什么策略,状态的模式的环境类Context选择什么状态策略则依赖于该环境的外部环境,相当于是由状态模式的环境类Context的外部环境将自身放进不同的具体状态策略中去。
策略模式所选的策略往往并不明显的告诉客户端它所选择的具体策略;而状态模式则相反,在状态模式里面,环境角色所处的状态是明显告诉给客户端的。