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

本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:http://blog.csdn.net/lovelion/article/details/17517213

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

我应该理解和掌握的:

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模式将每一个条件分支放进一个独立的类中,这使得你可以根据自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值