学习记录:《C++设计模式——李建忠主讲》6.“状态变化”模式
状态变化模式:在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定。状态变化模式为这一问题提供了一种解决方案。
典型模式:状态模式(State)、备忘录模式(Memento)。
一、状态模式
1.动机
在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生改变,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
2.作用
在运行时根据对象的状态来透明地更改对象的行为,而不会为对象操作和状态转化之间引入紧耦合。
3.定义
允许一个对象在其内部状态发生改变时改变它的行为,从而使对象看起来似乎修改了其行为。
4.代码
//原有代码
enum NetworkState
{
Network_Open,
Network_Close,
Network_Connect,
};
class NetworkProcessor{
NetworkState state;
public:
void Operation1(){
if (state == Network_Open){
//**********
state = Network_Close;
}
else if (state == Network_Close){
//..........
state = Network_Connect;
}
else if (state == Network_Connect){
//$$$$$$$$$$
state = Network_Open;
}
}
public void Operation2(){
if (state == Network_Open){
//**********
state = Network_Connect;
}
else if (state == Network_Close){
//.....
state = Network_Open;
}
else if (state == Network_Connect){
//$$$$$$$$$$
state = Network_Close;
}
}
public void Operation3(){
//**********
}
};
//运用状态模式后代码
class NetworkState{
public:
NetworkState* pNext;
virtual void Operation1()=;
virtual void Operation2()=;
virtual void Operation3()=;
virtual ~NetworkState(){}
};
class OpenState :public NetworkState{
static NetworkState* m_instance;
public:
static NetworkState* getInstance(){
//某个对象任何情况下应该只有一种状态,
//故采用单件模式使状态唯一
if (m_instance == nullptr) {
m_instance = new OpenState();
}
return m_instance;
}
void Operation1(){
//********** open状态下的行为1
pNext = CloseState::getInstance();
}
void Operation2(){
//..........
pNext = ConnectState::getInstance();
}
void Operation3(){
//$$$$$$$$$$
pNext = OpenState::getInstance();
}
};
//关闭状态和连接状态 略写
class CloseState:public NetworkState{ }
class ConnectState:public NetworkState{ } class NetworkProcessor{
NetworkState* pState;
public:
NetworkProcessor(NetworkState* pState){
this->pState = pState;
}
void Operation1(){
//...
pState->Operation1();
pState = pState->pNext;
//...
}
void Operation2(){
//...
pState->Operation2();
pState = pState->pNext;
//...
}
void Operation3(){
//...
pState->Operation3();
pState = pState->pNext;
//...
}
};
5.解析
这是一个表示网络行为的设计。网络对象有三种不同状态,open、close、connect。当网络对象收到其他对象的请求时,它根据自身当前状态做出不同的反应。例如,行为1的请求会让open状态变为close。
在状态模式中,引入了一个称为NetworkState的抽象类来表示网络的连接状态。NetworkState类为各不同操作状态的子类声明了一个公共接口。NetworkState子类实现与特定状态相关的行为。
NetworkProcessor类维护了NetWork连接状态对象,一旦状态改变,NetworkProcessor就会改变它使用的状态对象,所调用的NetWorkState类子类也会随之改变。
6.结构

其中,
1.Context(环境,如NetworkProcessor):定义客户感兴趣的接口;维护一个ConcreteState子类的实例,这个实例定义为当前状态;
2.State(状态,如NetworkState):定义一个接口以封装与Context的特定状态相关的行为;
3.ConcreteState(具体状态子类,如OpenState等):每一个子类实现一个与Context的一个状态相关的行为。
7.总结
1.State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象,但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。
2.为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的——即要么彻底转换过来,要么不转换。
3.如果State对象没有实例实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。
二、备忘录模式
1.动机
在软件构建过程中,某些对象的状态在转换过程中,可能由于某种需要,要求程序能够回溯到对象之前某个点时的状态。如果使用一些公有接口来让其他对象得到对象的状态,便会暴露对象的细节实现。
2.作用
既能实现对象状态的良好保存与恢复,但同时又不会因此而破坏对象本身的封装性。
3.定义
在不破坏对象封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
4.代码
//备忘录模式实现
class Memento
{
string state;
//..
public:
Memento(const string & s) : state(s) {}
string getState() const { return state; }
void setState(const string & s) { state = s; }
};
class Originator
{
string state;
//....
public:
Originator() {}
Memento createMomento() {
Memento m(state);
return m;
}
void setMomento(const Memento & m) {
state = m.getState();
}
};
int main()
{
Originator orginator;
//捕获对象状态,存储到备忘录
Memento mem = orginator.createMomento();
//... 改变orginator状态 //从备忘录中恢复
orginator.setMomento(memento);
}
5.解析
考虑一个图形编辑器,它支持图形对象之间的连线,而需要保证能撤销操作。
我们可用备忘录模式解决这一问题。一个备忘录是一个对象,它存储另一个对象在某个瞬间的内部状态,而后者称为备忘录的原发器。当需要设置原发器的检查点时,取消操作机制会向原发器请求一个备忘录。原发器用描述当前状态的信息初始化备忘录。只有原发器可以向备忘录中存取信息,备忘录对其他对象“不可见”。
6.结构

其中,
1.Memento(备忘录):存储原发器对象的内部状态。原发器对象根据需要决定备忘录存储原发器的哪些内部对象;防止原发器以为的对象访问备忘录。
2.Originator(原发器):原发器创建一个备忘录,用于记录当前时刻它的内部状态;使用备忘录恢复内部状态;
3.Caretaker(负责人,如main函数):负责保存好备忘录,但不能对备忘录的内容进行操作或检查。
7.总结
1.备忘录(Memento)存储原发器(Originator)对象的内部状态,在需要时恢复原发器状态。
2. Memento模式的核心是信息隐藏,即Originator需要向外接隐藏信息,保持其封装性。但同时需要将状态保持到外界(Memento)。
学习记录:《C++设计模式——李建忠主讲》6.“状态变化”模式的更多相关文章
- 学习记录:《C++设计模式——李建忠主讲》1.设计模式
1.学习目标 1)理解松耦合设计思想: 2)掌握面向对象设计原则: 3)掌握重构技法改善设计: 4)掌握GOF核心设计模式: 2.定义 每个设计模式描述了一个在我们周围不断重复发生的问题,以及该问题解 ...
- 学习记录:《C++设计模式——李建忠主讲》2.面向对象设计原则
1.课程内容: 重新认识面向对象:面向对象设计原则: 2.重新认识面向对象 1)理解隔离变化:从宏观层面来看,面向对象的构建方式更能适应软件的变化,将变化所带来的影响减为最小: 2)各司其职:从微观层 ...
- 学习记录:《C++设计模式——李建忠主讲》3.“组件协作”模式
“组件协作”模式:现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式.典型模式:Template M ...
- 学习记录:《C++设计模式——李建忠主讲》5.“对象性能”模式
对象性能模式:面向对象很好地解决了抽象地问题,但是必不可免地要付出一定地代价.对于通常情况来讲,面向对象地成本大都可以忽略不计,但某些情况,面向对象所带来地成本必须谨慎处理. 典型模式:单件模式(Si ...
- 学习记录:《C++设计模式——李建忠主讲》4.“单一职责”模式
单一职责模式:在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式:装饰模式(Decorator).桥 ...
- 学习记录:《C++设计模式——李建忠主讲》7.“领域规则”模式
领域规则模式:在特定领域中,某些变化虽然频繁,但可以抽象为某种规则.这时候,结合特定的领域,将问题抽象为语法规则,从而给出该领域下的一般性解决方案. 典型模式:解释器模式(Interpreter). ...
- 工厂模式(整理自李建忠<C++设计模式>视频)
整理自李建忠<C++设计模式>视频 一.导入:"对象创建"模式和工厂模式 工厂模式只是该模式下的一种. 二.举例说明 有这样一个场景:需要在MainForm中设计一个按 ...
- UWP学习记录10-设计和UI之控件和模式7
UWP学习记录10-设计和UI之控件和模式7 1.导航控件 Hub,中心控件,利用它你可以将应用内容整理到不同但又相关的区域或类别中. 中心的各个区域可按首选顺序遍历,并且可用作更具体体验的起始点. ...
- UWP学习记录9-设计和UI之控件和模式6
UWP学习记录9-设计和UI之控件和模式6 1.图形和墨迹 InkCanvas是接收和显示墨迹笔划的控件,是新增的比较复杂的控件,这里先不深入. 而形状(Shape)则是可以显示的各种保留模式图形对象 ...
随机推荐
- vue 页面滚动到原位置
哈哈哈,昨天登QQ的时候,意外发现有人看了我写的博客,居然还加了我,这就激起了我内心的小波澜啊 公司最近在做电商,用的前端框架依然是VUE 矩MAX(微信公众号)可以搜的到哦,安卓商店或苹果AppSt ...
- VoodooPad Mac笔记本
VoodooPad Mac笔记本 VoodooPad是记录您的笔记和想法的地方.想法,图片,列表,密码和妈妈的苹果派食谱.包括您需要跟踪和组织的所有内容,VoodooPad会与您一起成长而不会妨碍您. ...
- docker-以安装软件的方式介绍docker部分命令的使用
[root@ipha-dev71- docker]# docker search python # 搜索镜像 [root@ipha-dev71- docker]# docker pull centos ...
- 10.Nginx流行架构LNMP
1.什么是LNMP架构 LNMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写.L指Linux,N指Nginx,M一般指MySQL,也可以指MariaDB,P一般指PHP,也可以 ...
- spring security原理-学习笔记1-整体概览
整体概述 运行时环境 Spring Security 3.0需要Java 5.0 Runtime Environment或更高版本. 核心组件 SecurityContextHolder,Securi ...
- odoo联调
odoo联调(剑飞花 373500710) 1.准备工作 1.1.参考文章“odoo8.0+PyCharm4.5开发环境配置”配置好odoo开发环境 1.2.下载Chrome浏览器,安装. 1.3.下 ...
- Linux x64 Hadoop-2.4.1配置-解决错误Unable to load native-hadoop library for your platform
网上配置hadoop的教程一堆,各不尽相同,但没有一个是完整系统的. 下面给出遇到的错误的解决方法,相信能解决很多人的问题. 错误:Exception in thread "main&quo ...
- Veins(车载通信仿真框架)入门教程(四)——调试及记录结果
Veins(车载通信仿真框架)入门教程(四)——调试及记录结果 在Veins入门教程(三)最后的动图中(如下图)可以看到大大小小的光圈,这个怎么实现的呢? 很简单,以收到RTS消息为例,通过finHo ...
- SpringCloud之异常报警通知(八)
在之前整合降级的基础上,整合redis,达到报警的效果(redis的启动还是之前boot里面整合的redis) order-service pom.xml <dependency> < ...
- 【Windows系统】win10系统假死,窗口不能动,鼠标能动或不能动,最后蓝屏显示错误码: VIDEO_DXGKRNL_FATAL_ERROR 的解决办法
1. 问题的出现过程 最近博主自己用的 windows10 系统就碰到了这个问题. 一开始出现这个问题的征兆是鼠标会时不时地卡顿,一出现卡顿就会等个 1-3秒才能动.然后频繁卡顿(注意,这里根据经验就 ...