1. 描述
一个对象想内部状态类改变时,允许改变其行为。就是把一个对象的状态改到一系列状态类中,在状态类中控制条件判断、状态改变。
2. 特点
1) 将状态的行为都封装都状态类中,不同的状态不同的类。
2)状态转化条件在状态类中,不会出现状态随意变换的问题。
3) 可拓展性性强。
3.缺点
状态的越多,类越多
4.结构
1)上下文:维护当前状态。
2)抽象状态:定义封装状态变化条件的接口
3)具体状态:
5. UML
6.示例
#include "stdafx.h"
#include <iostream>
#include <Set>
//1.上下文声明
class AbstractScore;//类的声明只能用类的指针,如果需要调用方法,需要对类的方法也要声明
class ScoreContext
{
public:
AbstractScore * GetScoreState();
void SetScoreState(AbstractScore *abstractScore);
void Add(int Score);
private:
AbstractScore * _AbstractScore;
};
//2.抽象状态声明
class AbstractScore
{
public:
virtual void CheckState() = 0;
void AddScore(int score);
protected:
ScoreContext* _ScoreContext;
std::string _name;
int _Score;
};
//1.上下文实现
AbstractScore * ScoreContext:: GetScoreState()
{
return _AbstractScore;
};
void ScoreContext::SetScoreState(AbstractScore *abstractScore)
{
_AbstractScore = abstractScore;
};
void ScoreContext::Add(int Score)
{
_AbstractScore->AddScore(Score);
};
//2.抽象状态实现
void AbstractScore::AddScore(int score)
{
_Score += score;
std::cout << "加上:" << score << "分,\t当前分数" << _Score;
CheckState();
std::cout << "分,\t当前状态" << _ScoreContext->GetScoreState()->_name.c_str() << std::endl;
}
//3.具体状态
class PassScore :public AbstractScore
{
public:
PassScore(ScoreContext * scoreContext, int score);
void CheckState();
};
class FailScore:public AbstractScore
{
public:
FailScore(ScoreContext * scoreContext,int score)
{
_ScoreContext = scoreContext;
_name = "不及格";
_Score = score;
}
void CheckState()
{
if (_Score > 60)
{
AbstractScore * passScore = new PassScore(_ScoreContext, _Score);
_ScoreContext->SetScoreState(passScore);
}
}
};
PassScore::PassScore(ScoreContext * scoreContext, int score)
{
_ScoreContext = scoreContext;
_name = "及格";
_Score = score;
}
void PassScore::CheckState()
{
if (_Score <= 60)
{
FailScore * failScore = new FailScore(_ScoreContext, _Score);
_ScoreContext->SetScoreState(failScore);
}
}
int main()
{
ScoreContext *scoreContext = new ScoreContext;
FailScore * failScore = new FailScore(scoreContext, 0);
scoreContext->SetScoreState(failScore);
scoreContext->Add(40);
scoreContext->Add(40);
scoreContext->Add(-60);
getchar();
return 0;
}