设计动机
- 在软件构建过程中,某些对象的状态如果改变,其行为也会随之,而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
- 如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?
定义
允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。
结构
例子
传统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| enum NetworkState{ NetworkOpen, NetworkClose, NetworkConnect, }; class NetworkProcess{ NetworkState state; public: void operator1(){ if(state == NetworkOpen){
state = NetworkClose; }else if(state == NetworkClose){
state = NetworkConnect; }else if(state == NetworkConnect){
state = NetworkOpen; } } void operator2(){ if(state == NetworkOpen){
}else if(state == NetworkClose){
state = NetworkConnect; }else if(state == NetworkConnect){
state = NetworkOpen; } } }
|
状态模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| class OpenState; class CloseState; class ConnectState; class NetworkState{ public: NetworkState* pNext;
virtual void operator1() = 0; virtual void operator2() = 0; virtual ~NetworkState(){} }
class OpenState:public NetworkState{ static NetworkState* m_instance; public: static NetworkState* getInstance(){ if(m_instance == nullptr){ m_instance = new OpenState(); } return m_instance; } void operator1(){
pNext = CloseState::getInstance(); } }
class CloseState:public NetworkState{ static NetworkState* m_instance; public: static NetworkState* getInstance(){ if(m_instance == nullptr){ m_instance = new CloseState(); } return m_instance; } void operator1(){
pNext = ConnectState::getInstance(); } }
class ConnectState:public NetworkState{ static NetworkState* m_instance; public: static NetworkState* getInstance(){ if(m_instance == nullptr){ m_instance = new ConnectState(); } return m_instance; } void operator1(){
pNext = OpenState::getInstance(); } }
NetworkState* OpenState::m_instance = nullptr; NetworkState* CloseState::m_instance = nullptr; NetworkState* ConnectState::m_instance = nullptr;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class NetworkProcessor{ NetworkState* pState; public: NetworkProcessor(NetworkState* state):pState(state){
} void operator1(){ pState->operator1(); pState = pState->pNext; } }
|
总结
- State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。
- 为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的——即要么彻底转换过来,要么不转换。
- 如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。