您的位置:首页 > 其它

【设计模式学习笔记二十一】【行为模式】【状态模式(State)】

2015-02-08 14:11 741 查看
本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:/article/1610242.html

主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。

我应该理解和掌握的:

1)能够画出这个设计模式的架构框图;

2)能够根据架构框图写出对应的伪代码;

3)这个模式的应用场景,主要优缺点。

1.状态模式

假如有一个网络状态TCPConnection,他的状态处于若干不同的状态之一,例如:连接已建立(Established)、正在监听(Listening)、链接已关闭(Closed)。当一个TCPConnection对象收到其他对象的请求时,他根据自身当前状态(if 状态 else do)做出不同的反应。也就是说,系统中某个对象拥有多个状态,并且这些状态可以进行转换,而且对象在不同状态下的行为不同,便可以使用状态模式。他将对象中的状态抽离出来,封装到专门的状态类中,使得对象状态可以灵活变化。

(1)定义

状态模式:允许一个对象在其内部状态改变时改变他的行为,对象看起来似乎修改了他的类。

1) 状态模式结构图

核心是引入了抽象状态类和具体状态类,他是状态模式的核心。



2) 参与者

1) Context(环境):定义客户端感兴趣的接口;维护一个State抽象状态类,具体实现时实例化为具体状态类。
2) State(抽象状态类):定义一个接口以封装与Context的一个特定状态相关的行为。由不同的具体状态类去实现声明的接口。
3)ConcreteState(具体状态子类):每一个子类实现一个与context的一个状态相关的行为;每一个具体状态对象对应环境的一个具体状态,有着不同的行为。

3) 看图写代码

/*
** FileName     : StatePattern
** Author       : lin005
** Date         : 2015/02/10
** Description  : More information, please go to http://blog.csdn.net/amd123456789 */
#include<iostream>
using namespace std;
//抽象状态类
class State
{
public:
	//声明接口,由不同的状态子类实现
	virtual void handle() = 0;
};
//具体状态类,建立TCP连接
class TCPEstablished : public State
{
public:
	//实现父类接口
	virtual void handle()
	{
		cout<<"TCP is established"<<endl;
	}
};
//具体状态类,建立TCP监听
class TCPListen : public State
{
public:
	virtual void handle()
	{
		cout<<"TCP is listening"<<endl;
	}
};
//具体状态类,关闭TCP连接
class TCPClosed : public State
{
	virtual void handle()
	{
		cout<<"TCP is closed"<<endl;
	}
};
//环境类,持有抽象状态,通过注入不同的状态实现不同的行为。
class context
{
public:
	context():p_state(NULL){}
	void setState(State* state)
	{
		if(state)
		{
			p_state = state;
		}
		else
		{
			cout<<"no state,please set a state for me!"<<endl;
		}
	}
	void request()
	{
		p_state->handle();
	}
private:
	//持有状态类
	State* p_state;
};
//客户端测试
#define SAFE_DELETE(p) if(p){delete p; p = NULL;}
int main()
{
	//创建环境对象
	context* c = new context();
	//创建不同的具体状态对象
	State* establish = new TCPEstablished();
	State* listen = new TCPListen();
	State* closed = new TCPClosed();
	//注入状态对象
	c->setState(establish);
	c->request();
	//改变状态对象
	c->setState(listen);
	c->request();
	//改变状态对象
	c->setState(closed);
	c->request();

	SAFE_DELETE(establish);
	SAFE_DELETE(listen);
	SAFE_DELETE(closed);
	SAFE_DELETE(c);
	return 0;
}


(2)总结

1) 优点

a)
将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。State模式将所有与一个特定的状态相关的行为都放入到一个对象中。因为所有与状态相关的代码都存在于某一个State子类中,所以通过定义新的子类可以很容易的增加新的状态和转换。
b)
它使得状态转换显示化。为不同的状态引入独立的对象使得转换变得更加明确。
c)
State对象可被共享。从而减少系统中的对象个数。

2) 缺点

a) 增加了系统中类和对象的个数,导致系统运行开销增大。

b) 不太支持开闭原则,增加新的状态对象需要修改负责转换的源码码。

c) 状态模式的结构和实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,增加系统设计的难度。

(3)适用场景

1)
一个对象的行为取决于他的状态,并且它必须在运行时刻根据状态改变他们的行为。
2)
一个操作中含有庞大的多分支的条件语句,且这些分支语句依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。State模式将每一个条件分支放进一个独立的类中,这使得你可以根据自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: