随笔-174  评论-598  文章-0  trackbacks-0
作用:
允许一个对象在其内部状态改变时改变它的行为.

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/

    purpose:    State模式的演示代码
********************************************************************
*/


#ifndef STATE_H
#define STATE_H

class State;

class Context
{
public:
    Context(State
* pState);
    
~Context();
    
void Request();
    
void ChangeState(State *pState);

private:
    State 
*m_pState;
}
;

class State
{
public:
    
virtual ~State(){}

    
virtual void Handle(Context* pContext) = 0;
}
;

class ConcreateStateA
    : 
public State
{
public:
    
void Handle(Context* pContext);
}
;

class ConcreateStateB
    : 
public State
{
public:
    
void Handle(Context* pContext);
}
;

#endif

2)State.cpp
/********************************************************************
    created:    2006/08/05
    filename:     State.cpp
    author:        李创
                
http://www.cppblog.com/converse/

    purpose:    State模式的演示代码
********************************************************************
*/


#include 
"State.h"
#include 
<iostream>

Context::Context(State
* pState)
    : m_pState(pState)
{

}


Context::
~Context()
{
    delete m_pState;
    m_pState 
= NULL;
}


void Context::Request()
{
    
if (NULL != m_pState)
    
{
        m_pState
->Handle(this);
    }

}


void Context::ChangeState(State *pState)
{
    
if (NULL != m_pState)
    
{
        delete m_pState;
        m_pState 
= NULL;
    }

    
    m_pState 
= pState;
}


void ConcreateStateA::Handle(Context* pContext)
{
    std::cout 
<< "Handle by ConcreateStateA\n";
    
    
if (NULL != pContext)
    
{
        pContext
->ChangeState(new ConcreateStateB());
    }

}


void ConcreateStateB::Handle(Context* pContext)
{
    std::cout 
<< "Handle by ConcreateStateB\n";

    
if (NULL != pContext)
    
{
        pContext
->ChangeState(new ConcreateStateA());
    }

}


3)Main.cpp
/********************************************************************
    created:    2006/08/05
    filename:     Main.cpp
    author:        李创
                
http://www.cppblog.com/converse/

    purpose:    State模式的测试代码
********************************************************************
*/


#include 
"State.h"

int main()
{
    State 
*pState = new ConcreateStateA();
    Context 
*pContext = new Context(pState);
    pContext
->Request();
    pContext
->Request();
    pContext
->Request();

    delete pContext;

    
return 0;
}

posted on 2006-08-07 00:02 那谁 阅读(1392) 评论(3)  编辑 收藏 引用 所属分类: 设计模式

评论:
# re: 常见设计模式的解析和实现(C++)之十七-State模式 2006-08-25 15:39 | joyli
小弟手比较新,请教两个问题:

问题1:总感觉状态模式对于客户端开发人员来说,不是很友好
例如: pContext->Request();
pContext->Request();
pContext->Request();
问题2:要是一个状态可能会变为其他的状态,例如从 active 变成 complete或者 cancel 该怎么处理呢?  回复  更多评论
  
# re: 常见设计模式的解析和实现(C++)之十七-State模式 2006-08-30 08:51 | 罗家峰
每种状态用不同的处理方法呀.@joyli
我理解的不深刻,但是你说的这个问题应该是比较好解决的.  回复  更多评论
  
# re: 常见设计模式的解析和实现(C++)之十七-State模式 [未登录] 2008-03-04 13:44 | aaaa
现在个状态机模型看吧, 这个只是学习用的。 request时候new 了那么多的state 没见在哪里DELETE.  回复  更多评论
  


标题  
姓名  
主页
验证码 *
内容(提交失败后,可以通过“恢复上次提交”恢复刚刚提交的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
[使用Ctrl+Enter键可以直接提交]
.NET频道  博客园社区  闪存
网站导航: