设计模式笔记-State模式

原创 2016年05月31日 21:07:45

状态模式:事物在不同状态下会有不同表现(动作),经过不同动作后,又会转移到下一个不同的状态。这种问题可以用Switch/Case(if-else)搞定, 但如果case语句很多,就很麻烦,这种实现也没有将逻辑和动作分离,后期维护得不到保证!加case语句要修改原来代码,违反了“对扩展开放,对修改关闭”的原则!State 模式将每一个case分支都封装到独立的类中!

状态模式的具体实现类中有一个指向Context的引用。State 模式很好地实现了对象的状态逻辑和动作实现的分离, 状态逻辑分布在State 的派生类中实现,而动作实现则可以放在 Context 类中实现(这也是为什么 State 派生类需要拥有一个指向 Context 的指针)。这使得两者的变化相互独立, 改变 State 的状态逻辑可以很容易复用 Context 的动作, 也可以在不影响 State 派生类的前提下创建Context 的子类来更改或替换动作实现。


上下文环境(Context):定义客户需要的接口并维护一个ConcreteState实例,将与状态相关的操作委托给它来处理。

抽象状态(State):定义一个接口以封装使用上下文环境的的一个特定状态相关的行为。

具体状态(Concrete State):实现象状态定义的接口, 每一子类实现一个与Context的一个状态相关的行为。 

这个状态模式,网上的实现我觉得都不怎么好,主要是实现细节方面的!

这一篇,每次状态转换都new一个对象,delete一个对象,申请&释放内存好像挺耗时的!它描述的状态不是封闭的,我自己在实现的时候,就出现了问题--说出来可能丢人,就是new一个对象传入时,如果对象定义在后面C++是识别不到的,前向声明也没用,只能把.h和.cpp文件分开写,然后互相包含对方的.h文件!

另一篇,我觉得实现的很好,不过是PHP版本的,PHP是弱类型语言,有一些方便之处,比如所有状态类事先在Context类构造函数中new好。我在用C++改写时遇到了问题,什么头文件你包含我,我包含你的,太烦了,没成功!就简化成下面这样吧,不停申请&释放是挺耗时的。可以理解为一个开关,只有开和关两种状态!

class Context;

class LiftState {
public:
	LiftState();
	virtual ~LiftState();
	virtual void open(Context*) = 0;
	virtual void close(Context*) = 0;
};

class Context
{
public:

	Context();
	~Context();
	void setLiftState(LiftState* ls);
	LiftState* getLiftState();
	void open();
	void close();
private:
	LiftState* m_liftState;
};
LiftState::LiftState() {}

LiftState::~LiftState() {}

Context::Context() { m_liftState = NULL; }
Context::~Context() {}
void Context::setLiftState(LiftState* ls) {
	if (m_liftState) delete m_liftState;
	m_liftState = ls;
}
LiftState* Context::getLiftState() { return m_liftState; }
void Context::open() { m_liftState->open(this); }
void Context::close() { m_liftState->close(this); }
class OpenState : public LiftState {
public:
	OpenState();
	void open(Context* );
	void close(Context* );
};
OpenState::OpenState() {}
void OpenState::open(Context* ctx) {}

void OpenState::close(Context* ctx) {
	cout << "open->close!" << endl;
	ctx->setLiftState(new CloseState());
	ctx->getLiftState()->close(ctx);
}
#include"openstate.h"

class CloseState : public LiftState {
public:
	CloseState();
	void open(Context* );
	void close(Context* );
};
#include"openstate.h"
#include"closestate.h"

CloseState::CloseState() {}
void CloseState::open(Context* ctx) {
	cout << "close->open!" << endl;
	ctx->setLiftState(new OpenState());
	ctx->getLiftState()->open(ctx);
}

void CloseState::close(Context* ctx) {}
用户代码:

int main()
{
	Context* ct = new Context();
	ct->setLiftState(new OpenState());
	ct->open();
	ct->close();
	ct->open();
	return 0;
}

如果有想测试这个代码的,记得把各个代码块分文件存放!因为两个状态的CPP文件相互包含了对方的头文件,相互包含只能是声明,不能是定义!

代码里,state类里是通过传参的方式使用Context类的,而不能组合一个Context*类型的变量,因为Context类里已经组合了一个State*的变量了,相互包含的话,上面那条delete语句后,把调用setLiftState函数的指针对象自身都删除了,因为删除的State类对象指针中包含了Context对象指针!

版权声明:本文为博主原创文章,未经博主允许不得转载。

【设计模式】学习笔记14:状态模式(State)

认识状态模式 假设有一个糖果机, 它的工作状态图如下:要用代码实现糖果机的功能, 如果不用状态模式: 一种方法是创建一个类,它的作用就是一个状态机,对每一个动作,我们都创建了一个对应的方法,这些方法...
  • shuangde800
  • shuangde800
  • 2013年08月22日 00:15
  • 19685

设计模式学习笔记--Strategy、State

最近在看设计模式的,防止遗忘,总结一下,如有不足还望指正! 策略模式:(strategy)定义算法家族,分别封装起来,让他们之间可以相互替换。此模式可以让算法的变化,不影响使用算法的用户。 类图如下:...
  • smartboy_01
  • smartboy_01
  • 2014年12月30日 22:32
  • 531

大话设计模式 读书笔记

大话设计模式 读书笔记 着重从c#代码角度分析 学习心得: 学设计模式,不需要是否能立刻理解和记忆,无需着力首先是UML图 再从设计模式到UML图 从UML图到代码 其次知道各种模式的应用场景即可...
  • jiangdmdr
  • jiangdmdr
  • 2017年03月01日 18:50
  • 328

"围观"设计模式(21)--行为型之状态模式(State Pattern)

状态模式--允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。----百度百科 个人理解 状态模式应该说可以理解为某种状态下,程序的执行流程可能会发生变化,类...
  • wangyang1354
  • wangyang1354
  • 2016年06月13日 15:11
  • 3412

设计模式 - 状态模式(state pattern) 详解

状态模式(state pattern) 详解本文地址: http://blog.csdn.net/caroline_wendy状态模式(state pattern): 允许对象在内部状态改变时改变它的...
  • u012515223
  • u012515223
  • 2014年07月11日 17:42
  • 2100

【JS设计模式】状态模式的代码示例

1. 概述  当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。2. 解决的问题  主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同...
  • itpinpai
  • itpinpai
  • 2016年06月03日 17:45
  • 3512

JAVA设计模式(18):行为型-状态模式(State)

“人有悲欢离合,月有阴晴圆缺”,包括人在内,很多事物都具有多种状态,而且在不同状态下会具有不同的行为,这些状态在特定条件下还将发生相互转换。就像水,它可以凝固成冰,也可以受热蒸发后变成水蒸汽,水可以流...
  • taozi8023
  • taozi8023
  • 2016年05月19日 20:26
  • 6362

Java设计模式——状态模式(STATE PATTERN)

场景一 描述:现在城市发展很快,百万级人口的城市一堆一堆的,那其中有两个东西的发明在城市的发展中起到非常重要的作用:一个是汽车,一个呢是...,猜猜看,是什么?是电梯!汽车让城市可以横向扩展,电梯让城...
  • u012401711
  • u012401711
  • 2016年09月26日 23:45
  • 2687

JAVA设计模式之 状态模式【State Pattern】

一、概述     当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状...
  • l416112167
  • l416112167
  • 2014年11月12日 23:48
  • 2645

设计模式之State模式(笔记)

状态模式:当一个对象的内在状态发生改变时允许改变其内在行为,这个对象看起来像是改变了其类。 状态模式主要是解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状...
  • qq_16687803
  • qq_16687803
  • 2015年06月16日 09:57
  • 498
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式笔记-State模式
举报原因:
原因补充:

(最多只允许输入30个字)