1定义

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

2类图

角色分析

State抽象状态角色,接口或者抽象类,负责状态定义,并且封装环境角色以实现状态切换

ConcreteState具体状态角色,完成两个职责:本状态行为管理以及趋向状态处理--==本状态要做的事和本状态如何过度到其他状态

Context环境角色,定义客户端需要的接口,并且负责具体状态的切换

实现

#include<iostream>
using namespace std; //前项声明
class Context;
//抽象状态类定义
class State
{
protected:
State(){}
public:
virtual~State() =
{};
void setContext(Context *x)
{
_context = x;
}
virtual void handler1() = ;
virtual void handler2() = ;
private:
Context *_context;
}; //具体状态定义
class ConcreteState1 :public State
{
public:
ConcreteState1(){}
~ConcreteState1(){} void handler1()
{
cout << "ConcreteState1::handler1" << endl;
}
void handler2()
{
cout << "ConcreteState1::handler2" << endl;
}
private: }; //具体状态定义
class ConcreteState2 :public State
{
public:
ConcreteState2(){}
~ConcreteState2(){} void handler1()
{
cout << "ConcreteState2::handler1" << endl;
}
void handler2()
{
cout << "ConcreteState2::handler2" << endl;
}
private: }; //环境类
class Context
{
public:
Context()
:Sta1(new ConcreteState1)
,Sta2(new ConcreteState2)
{}
State* getCurrentState()
{
return CurrentState;
}
void SetCurrentState(State* s)
{
CurrentState = s;
CurrentState->setContext(this);
}
void handler1()
{
CurrentState->handler1();
}
void handler2()
{
CurrentState->handler2();
}
~Context(){}
private:
//当前状态则是所有状态中的一种
State *CurrentState;
//所有状态应当定义为static比较合适
State *Sta1;
State *Sta2;
};
void TestState()
{
Context * context = new Context();
context->SetCurrentState(new ConcreteState1()); context->handler1();
context->handler2();
context->SetCurrentState(new ConcreteState2());
context->handler1();
context->handler2();
}

 

3应用

①优点

状态模式隐藏了状态的 变化过程,他的切换引起了行为的变化。我们只看到行为变化,而没有状态变化

结构清晰,避免过多switch或者if语句的使用

体现开闭原则和单一职责原则,每个状态都是一个子类

封装性良好,状态变化在内部体现,外界调用不知道这一点

②缺点

子类越多会带来类膨胀的问题

4使用场景

行为随着状态改变而改变

条件分之判断语句的替代者

5注意事项

状态模式适用于当某个对象在他的状态发生变化时,他的行为也随之变化,也就是行为受状态约束的情况下使用状态模式,而且使用对象时状态不超过5个

6最佳实践

TCP三个状态切换:等待状态,连接状态,断开状态。

工作流开发:状态机管理。

{

最新文章

  1. XSS 防御方法总结
  2. memcache与memcached的区别
  3. winform 异步添加文本提示
  4. 区分各浏览器的CSS hack(包括360、搜狗、opera)
  5. App开发流程之使用分类(Category)和忽略编译警告(Warning)
  6. Linux su和sudo命令的区别,并获得root权限
  7. [OrangePi] Features (the features of Loboris&#39;s Images)
  8. C# Driver LINQ Tutorial
  9. wikioi 1010 过河卒
  10. CSS 命名规范及标题供参考与学习
  11. VI一个终端编辑多个文件的命令
  12. js 全国城市3级联动
  13. js中的数组和字符串的一些方法
  14. spring之事务
  15. python实现线性回归
  16. MySQL InnoDB独立表空间模式的优点和缺点介绍
  17. Ext数字格式化
  18. sql server 实现多表连接查询
  19. 多进程wait、僵尸进程、孤儿进程、prctl
  20. HTML5 manifest离线缓存技术

热门文章

  1. 生信-cufflinks输入输出文件分析
  2. android 显示internet 图片
  3. js null, undefined, NaN, ‘’, false, 0, ==, === 全验证
  4. tensorflow(二)----线程队列与io操作
  5. POJ - 3308 Paratroopers (最小点权覆盖)
  6. TOSCA自动化测试工具--openURL
  7. UI自动化测试框架之Selenium关键字驱动 (转)
  8. 微服务—分布式服务追踪sleuth和zipkin
  9. qq第三方登录网站接口
  10. hadoop HA + kerberos HA集群搭建问题和测试总结