学习记录:《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)则是可以显示的各种保留模式图形对象 ...
随机推荐
- chrome devtools tip(2)--自定义代码片段,构建你的工具箱
平常开发中,有些代码片段常常用到的,比如,获取 url 参数,rgb转16进制,打印下当前页面的性能数据,给所有的 span 加个样式, 防抖节流,fetch接口,类似 jquery这样的顺手 选择 ...
- 《编写可维护的JavaScript》 笔记
<编写可维护的JavaScript> 笔记 我的github iSAM2016 概述 本书的一开始介绍了大量的编码规范,并且给出了最佳和错误的范例,大部分在网上的编码规范看过,就不在赘述 ...
- Redis(八)理解内存
Redis所有的数据都存在内存中,当前内存虽然越来越便宜,但跟廉价的硬盘相比成本还是比较昂贵,因此如何高效利用Redis内存变得非常重要. 高效利用Redis内存首先需要理解Redis内存消耗在哪里, ...
- (二)AS给button添加点击事件
三种方法给Button添加点击事件 (一)通过button的id,添加继承View.OnClickListener的监听实现 <Button android:id="@+id/btn_ ...
- github实用的搜索小技巧
查资源,学习优秀的框架,搜索是一种能力! 作为程序猿开发中最大的同性交友网站,github当之无愧,里面有很多优秀的开源框架,各种技术大佬混迹其中,有他们总结的学习教程,造好的轮子(开发的各种工具,技 ...
- 最常用 最完整 最清晰 的git使用命令大全!
Git 常用命令 初始化项目步骤 mkdir WebApp //创建文件夹 cd WebApp //进入到该文件夹 git init //初始化 touch README //生成README git ...
- Unity5-ABSystem(四):AssetBundle依赖
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/lodypig/article/detai ...
- Windows许可证即将过期怎么办?
最近在使用电脑的时候,一开机就会弹窗出现:Windows 许可证即将过期.我勒个去,windows还会过期啊. 我搜遍全网,发现了一个很棒的 Windows10 永久激活的工具,而且没有广告什么乱七八 ...
- 处理echarts用到的数据格式。。。
1.需求将数据组装: 将typeNumMap中 键为 '1' 的放在数组series 索引为1的data数组中, 将'2'放在索引为2的data数组中,如果 typeNumMap 中没有 对应的 1, ...
- 学习c++11 ThreadPool【转】
#ifndef THREAD_POOL_H #define THREAD_POOL_H #include <vector> #include <queue> #include ...