状态模式(State Pattern) :允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行为型模式。
状态模式包含如下角色:
既然是状态模式,加上状态图,对状态转换间的理解会清晰很多:
#include <iostream> #include "Context.h" #include "ConcreteStateA.h" #include "ConcreteStateB.h" using namespace std; int main(int argc, char *argv[]) { char a = '0'; if('0' == a) cout << "yes" << endl; else cout << "no" << endl; Context * c = new Context(); c->request(); c->request(); c->request(); delete c; return 0; }
/////////////////////////////////////////////////////////// // Context.h // Implementation of the Class Context // Created on: 09-十月-2014 17:20:59 // Original author: colin /////////////////////////////////////////////////////////// #if !defined(EA_F245CF81_2A68_4461_B039_2B901BD5A126__INCLUDED_) #define EA_F245CF81_2A68_4461_B039_2B901BD5A126__INCLUDED_ #include "State.h" class Context { public: Context(); virtual ~Context(); void changeState(State * st); void request(); private: State *m_pState; }; #endif // !defined(EA_F245CF81_2A68_4461_B039_2B901BD5A126__INCLUDED_)
/////////////////////////////////////////////////////////// // Context.cpp // Implementation of the Class Context // Created on: 09-十月-2014 17:20:59 // Original author: colin /////////////////////////////////////////////////////////// #include "Context.h" #include "ConcreteStateA.h" Context::Context(){ //default is a m_pState = ConcreteStateA::Instance(); } Context::~Context(){ } void Context::changeState(State * st){ m_pState = st; } void Context::request(){ m_pState->handle(this); }
/////////////////////////////////////////////////////////// // ConcreteStateA.h // Implementation of the Class ConcreteStateA // Created on: 09-十月-2014 17:20:58 // Original author: colin /////////////////////////////////////////////////////////// #if !defined(EA_84158F08_E96A_4bdb_89A1_4BE2E633C3EE__INCLUDED_) #define EA_84158F08_E96A_4bdb_89A1_4BE2E633C3EE__INCLUDED_ #include "State.h" class ConcreteStateA : public State { public: virtual ~ConcreteStateA(); static State * Instance(); virtual void handle(Context * c); private: ConcreteStateA(); static State * m_pState; }; #endif // !defined(EA_84158F08_E96A_4bdb_89A1_4BE2E633C3EE__INCLUDED_)
/////////////////////////////////////////////////////////// // ConcreteStateA.cpp // Implementation of the Class ConcreteStateA // Created on: 09-十月-2014 17:20:58 // Original author: colin /////////////////////////////////////////////////////////// #include "ConcreteStateA.h" #include "ConcreteStateB.h" #include "Context.h" #include <iostream> using namespace std; State * ConcreteStateA::m_pState = NULL; ConcreteStateA::ConcreteStateA(){ } ConcreteStateA::~ConcreteStateA(){ } State * ConcreteStateA::Instance() { if ( NULL == m_pState) { m_pState = new ConcreteStateA(); } return m_pState; } void ConcreteStateA::handle(Context * c){ cout << "doing something in State A.\n done,change state to B" << endl; c->changeState(ConcreteStateB::Instance()); }
运行结果:
在状态模式结构中需要理解环境类与抽象状态类的作用:
TCPConnection
这个示例来自《设计模式》,展示了一个简化版的TCP协议实现; TCP连接的状态有多种可能,状态之间的转换有相应的逻辑前提; 这是使用状态模式的场合;
状态图:
结构图:
时序图:
状态模式的优点
状态模式的缺点
在以下情况下可以使用状态模式:
状态模式在工作流或游戏等类型的软件中得以广泛使用,甚至可以用于这些系统的核心功能设计,如在政府OA办公系统中,一个批文的状态有多种:尚未办理;正在办理;正在批示;正在审核;已经完成等各种状态,而且批文状态不同时对批文的操作也有所差异。使用状态模式可以描述工作流对象(如批文)的状态转换以及不同状态下它所具有的行为。
共享状态
简单状态模式与可切换状态的状态模式
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8