本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:http://blog.youkuaiyun.com/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.youkuaiyun.com/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模式将每一个条件分支放进一个独立的类中,这使得你可以根据自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。