那谁的技术博客

感兴趣领域:高性能服务器编程,存储,算法,Linux内核
随笔 - 210, 文章 - 0, 评论 - 1183, 引用 - 0
数据加载中……

常见设计模式的解析和实现(C++)之十七-State模式

作用:
允许一个对象在其内部状态改变时改变它的行为.

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 那谁 阅读(4685) 评论(5)  编辑 收藏 引用 所属分类: 设计模式

评论

# re: 常见设计模式的解析和实现(C++)之十七-State模式   回复  更多评论   

小弟手比较新,请教两个问题:

问题1:总感觉状态模式对于客户端开发人员来说,不是很友好
例如: pContext->Request();
pContext->Request();
pContext->Request();
问题2:要是一个状态可能会变为其他的状态,例如从 active 变成 complete或者 cancel 该怎么处理呢?
2006-08-25 15:39 | joyli

# re: 常见设计模式的解析和实现(C++)之十七-State模式   回复  更多评论   

每种状态用不同的处理方法呀.@joyli
我理解的不深刻,但是你说的这个问题应该是比较好解决的.
2006-08-30 08:51 | 罗家峰

# re: 常见设计模式的解析和实现(C++)之十七-State模式 [未登录]  回复  更多评论   

现在个状态机模型看吧, 这个只是学习用的。 request时候new 了那么多的state 没见在哪里DELETE.
2008-03-04 13:44 | aaaa

# re: 常见设计模式的解析和实现(C++)之十七-State模式   回复  更多评论   

我觉得状态变化的逻辑应体现在ChangeState上,而不是在子类上控制。
因为子类之间是没有什么关系的。
2010-02-08 16:31 | 茂也

# re: 常见设计模式的解析和实现(C++)之十七-State模式   回复  更多评论   

@茂也
同意,还有对外层来说Request的同时改变状态,从外层来说不知道改了,更不知道改成什么,这个是想达到这个效果吗还是?
2010-09-19 17:36 | 张崇彪

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理