作用:
允许一个
对象在其内部状态改变时改变它的行为.
UML结构图:
解析:
State模式主要解决的是在开发中时常遇到的根据不同的状态需要进行不同的处理操作的问题,而这样的问题,大部分人是采用switch-case语句进行处理的,这样会造成一个问题:分支过多,而且如果加入一个新的状态就需要对原来的代码进行编译.State模式采用了对这些不同的状态进行封装的方式处理这类问题,当状态改变的时候进行处理然后再切换到另一种状态,也就是说把状态的切换责任交给了具体的状态类去负责.同时,State模式和Strategy模式在图示上有很多相似的地方,需要说明的是两者的思想都是一致的,只不过封装的东西不同:
State模式封装的是不同的状态,而Stategy模式封装的是不同的算法.
实现:
1)State.h
/**/
/********************************************************************
created: 2006/08/05
filename: State.h
author: 李创
http://www.cppblog.com/converse/
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
purpose: State模式的演示代码
*********************************************************************/
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
#ifndef STATE_H
#define
STATE_H
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
class
State;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
class
Context
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
public:
Context(State* pState);
~Context();
void Request();
void ChangeState(State *pState);
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
private:
State *m_pState;
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
class
State
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
public:
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
virtual ~State()
{}
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
virtual void Handle(Context* pContext) = 0;
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
class
ConcreateStateA
:
public
State
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
public:
void Handle(Context* pContext);
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
class
ConcreateStateB
:
public
State
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
public:
void Handle(Context* pContext);
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
#endif
2)State.cpp
/**/
/********************************************************************
created: 2006/08/05
filename: State.cpp
author: 李创
http://www.cppblog.com/converse/
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
purpose: State模式的演示代码
*********************************************************************/
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
#include
"
State.h
"
#include
<
iostream
>
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
Context::Context(State
*
pState)
: m_pState(pState)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
Context::
~
Context()
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
delete m_pState;
m_pState = NULL;
}
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
void
Context::Request()
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
if (NULL != m_pState)
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
m_pState->Handle(this);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
void
Context::ChangeState(State
*
pState)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
if (NULL != m_pState)
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
delete m_pState;
m_pState = NULL;
}
m_pState = pState;
}
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
void
ConcreateStateA::Handle(Context
*
pContext)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
std::cout << "Handle by ConcreateStateA\n";
if (NULL != pContext)
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
pContext->ChangeState(new ConcreateStateB());
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
void
ConcreateStateB::Handle(Context
*
pContext)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
std::cout << "Handle by ConcreateStateB\n";
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
if (NULL != pContext)
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
pContext->ChangeState(new ConcreateStateA());
}
}
3)Main.cpp
/**/
/********************************************************************
created: 2006/08/05
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
purpose: State模式的测试代码
*********************************************************************/
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
#include
"
State.h
"
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
int
main()
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
State *pState = new ConcreateStateA();
Context *pContext = new Context(pState);
pContext->Request();
pContext->Request();
pContext->Request();
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
delete pContext;
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
return 0;
}