Chapter12:状态模式

先唠叨一句:面向对象设计其实就是希望做到代码的责任分解。

状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

先赏张图:


状态模式的好处与用处:
状态模式的好处是:
将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个具体(ConcreteState)的状态类中,所以通过定义新的子类可以很容易地增加新的状态和转换。这样做的目的就是为了消除庞大的条件分支语句。状态模式通过把各种状态转移逻辑分布到状态(state)的子类之间,来减少相互间的依赖。
那我们什么时候考虑使用状态模式呢?
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
实际应用一个
例如:我们上学时的学习状态随着时间的不同而不同。早晨学习精神百倍,中午又饿又困,下午有恢复精神等等

 实际应用:

工程结构:

(1)状态以及学习时间类 State.h ;ConcreteState.cpp

(2)客户端类:StateApp.cpp

 

(1)State.h

#ifndef _STATE_H_
#define _STATE_H_
#include
<string>
#include
<iostream>
using namespace std;
#define NOON 12 // 中午
#define AFTERNOON 13 // 下午
#define EVENING 17 // 傍晚
#define NIGHT 21 // 晚上
/************************************************************************
* description: 抽象状态
* remark:
***********************************************************************
*/
class StudyTime;
class CState
{
public:
virtual void StudyState(StudyTime* pSTime) = 0;
};
/************************************************************************
* description: 上午学习状态
* remark:
***********************************************************************
*/
class MorningState : public CState
{
public:
void StudyState(StudyTime* pSTime);
};
/************************************************************************
* description: 中午学习状态
* remark:
***********************************************************************
*/
class NoonState : public CState
{
public:
void StudyState(StudyTime* pSTime);
};
/************************************************************************
* description: 下午学习状态
* remark:
***********************************************************************
*/
class AfternoonState : public CState
{
public:
void StudyState(StudyTime* pSTime);
};
/************************************************************************
* description: 休息状态
* remark:
***********************************************************************
*/
class RestState : public CState
{
public:
void StudyState(StudyTime* pSTime);
};
/************************************************************************
* description: 睡眠状态
* remark:
***********************************************************************
*/
class SleepState : public CState
{
public:
void StudyState(StudyTime* pSTime);
};
/************************************************************************
* description: 晚间工作状态
* remark:
***********************************************************************
*/
class EveningState : public CState
{
public:
void StudyState(StudyTime* pSTime);
};
/************************************************************************
* description: 学习类
* remark:
***********************************************************************
*/
class StudyTime
{
public:
// 初始化为:早上学习状态
StudyTime() : m_pCurState(NULL)
, m_bFinish(
false)
, m_nCurTime(
0)
{
m_pCurState
= new MorningState();
}
int GetCurTime(void)
{
return m_nCurTime;
}
void SetCurTime(const int nTime)
{
m_nCurTime
= nTime;
}
bool IsStudyFinished(void)
{
return m_bFinish;
}
void SetStudyProgress(const bool bFinished)
{
m_bFinish
= bFinished;
}
void SetState(CState* pState)
{
m_pCurState
= pState;
}
void StudyState(void)
{
m_pCurState
->StudyState(this);
}
private:
CState
* m_pCurState;
int m_nCurTime;
bool m_bFinish;
};
#endif// _STATE_H_

 


(2)ConcreteState.cpp

#include "State.h"
/************************************************************************
* description: 上午学习状态
* remark:
***********************************************************************
*/
void MorningState::StudyState(StudyTime* pSTime)
{
if (NULL != pSTime)
{
if (NOON > pSTime->GetCurTime())
{
cout
<< "当前时间:" << pSTime->GetCurTime() << "点:上午学习,效率很高!" << endl;
}
else
{
// 超过12点,转入中午学习状态
pSTime->SetState(new NoonState());
pSTime
->StudyState();
}
}
}
/************************************************************************
* description: 中午学习状态
* remark:
***********************************************************************
*/
void NoonState::StudyState(StudyTime* pSTime)
{
if (NULL != pSTime)
{
if (AFTERNOON > pSTime->GetCurTime())
{
cout
<< "当前时间:" << pSTime->GetCurTime() << "点:学不进去…饿了,吃午饭。学不进去…困了,要午休。" << endl;
}
else
{
// 超过13点,转入下午学习状态
pSTime->SetState(new AfternoonState());
pSTime
->StudyState();
}
}
}
/************************************************************************
* description: 下午学习状态
* remark:
***********************************************************************
*/
void AfternoonState::StudyState(StudyTime* pSTime)
{
if (NULL != pSTime)
{
if (EVENING > pSTime->GetCurTime())
{
cout
<< "当前时间:" << pSTime->GetCurTime() << "点:下午状态不错,努力学习ing…" << endl;
}
else
{
// 超过17点,转入傍晚学习状态
pSTime->SetState(new EveningState());
pSTime
->StudyState();
}
}
}
/************************************************************************
* description: 休息状态
* remark:
***********************************************************************
*/
void RestState::StudyState(StudyTime* pSTime)
{
if (NULL != pSTime)
{
cout
<< "当前时间:" << pSTime->GetCurTime() << "点:学习计划完成,休息啦!" << endl;
}
}
/************************************************************************
* description: 睡眠状态
* remark:
***********************************************************************
*/
void SleepState::StudyState(StudyTime* pSTime)
{
if (NULL != pSTime)
{
cout
<< "当前时间:" << pSTime->GetCurTime() << "点:不行了…睡着了…ZzZzZz…(口水流到书上了…)" << endl;
}
}
/************************************************************************
* description: 晚间工作状态
* remark:
***********************************************************************
*/
void EveningState::StudyState(StudyTime* pSTime)
{
if (NULL != pSTime)
{
if (pSTime->IsStudyFinished())
{
// 如果学习任务完成,转入休息状态
pSTime->SetState(new RestState());
pSTime
->StudyState();
}
else
{
if (NIGHT > pSTime->GetCurTime())
{
cout
<< "当前时间:" << pSTime->GetCurTime() << "点:悬梁刺股,熬夜学习…" << endl;
}
else
{
// 超过21点,转入睡眠状态
pSTime->SetState(new SleepState());
pSTime
->StudyState();
}
}
}
}

 

(3)StateApp.cpp

// StateApp.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
"State.h"
int _tmain(int argc, _TCHAR* argv[])
{
StudyTime
* pTime = NULL;
pTime
= new StudyTime();
// 开始一天的学习
int nHhour = 7;
do
{
// 到晚上认为学习计划任务完成
if (nHhour >= NIGHT)
{
pTime
->SetStudyProgress(true);
}
pTime
->SetCurTime(nHhour % 24);
pTime
->StudyState();
nHhour
++;
}
while (nHhour % 24 != 0);
if (NULL != pTime)
{
delete pTime;
pTime
= NULL;
}
system(
"pause");
return 0;
}

 





posted @ 2010-08-27 23:21  奋斗の机器  阅读(242)  评论(0编辑  收藏  举报