行为型模式之状态模式(State)

来源:互联网 发布:淘宝女装哪个货源好 编辑:程序博客网 时间:2024/05/30 05:05
1. 意图
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
2. 动机
考虑一个表示网络连接的类T C P C o n n e c t i o n。一个T C P C o n n e c t i o n对象的状态处于若干不同状态之一: 连接已建立( E s t a b l i s h e d)、正在监听( L i s t e n i n g )、连接已关闭( C l o s e d )。当一个T C P C o n n e c t i o n对象收到其他对象的请求时, 它根据自身的当前状态作出不同的反应。例如,一个O p e n请求的结果依赖于该连接是处于连接已关闭状态还是连接已建立状态。S t a t e模式描述了T C P C o n n e c t i o n如何在每一种状态下表现出不同的行为。
这一模式的关键思想是引入了一个称为T C P S t a t e的抽象类来表示网络的连接状态。T C P S t a t e类为各表示不同的操作状态的子类声明了一个公共接口。T C P S t a t e的子类实现与特定状态相关的行为。例如, TCPEstablished和T C P C l o s e d类分别实现了特定于T C P C o n n e c t i o n的
连接已建立状态和连接已关闭状态的行为。


T C P C o n n e c t i o n类维护一个表示T C P连接当前状态的状态对象(一个T C P S t a t e子类的实例)。T C P C o n n e c t i o n类将所有与状态相关的请求委托给这个状态对象。T C P C o n n e c t i o n使用它的T C P S t a t e子类实例来执行特定于连接状态的操作。
一旦连接状态改变, T C P C o n n e c t i o n对象就会改变它所使用的状态对象。例如当连接从已建立状态转为已关闭状态时, TCPConnection 会用一个T C P C l o s e d的实例来代替原来的T C P E s t a b l i s h e d的实例。

3.结构

• C o n t e x t(环境,如T C P C o n n e c t i o n )
— 定义客户感兴趣的接口。

— 维护一个C o n c r e t e S t a t e子类的实例,这个实例定义当前状态。
• S t a t e(状态,如T C P S t a t e )
— 定义一个接口以封装与C o n t e x t的一个特定状态相关的行为。
• ConcreteState subclasses(具体状态子类,如TCPEstablished, TCPListen, TCPClosed)
— 每一子类实现一个与C o n t e x t的一个状态相关的行为。


4.举例

#ifndef STATE_H#define STATE_H#include <iostream>using std::cout;using std::endl;class TCPState{public:virtual bool Open(){return false;};virtual bool Close(){return false;};virtual bool Acknowledge(){return false;};};class TCPEstablishd : public TCPState{public:virtual bool Open(){cout<<"It had already been Opened!"<<endl;return false;}virtual bool Close(){cout<<"It closes!"<<endl;return true;}virtual bool Acknowledge(){cout<<"It had already been connected!"<<endl;return false;}};class TCPListen : public TCPState{public:virtual bool Open(){cout<<"It had already been Opened!"<<endl;return false;}virtual bool Close(){cout<<"It has no connection!"<<endl;return false;}virtual bool Acknowledge(){cout<<"It connects!"<<endl;return true;}};class TCPClosed : public TCPState{public:virtual bool Open(){cout<<"It Opens!"<<endl;return true;}virtual bool Close(){cout<<"It had already been closed!"<<endl;return false;}virtual bool Acknowledge(){cout<<"It is closed now!"<<endl;return false;}};class TCPConnection{private:TCPState* pTCPState;public:TCPConnection(){pTCPState=new TCPClosed;}TCPConnection(TCPState* tmp){pTCPState=tmp;}~TCPConnection(){delete pTCPState;}void Open(){if(pTCPState->Open()){delete pTCPState;pTCPState=new TCPListen;}};void Close(){if(pTCPState->Close()){delete pTCPState;pTCPState=new TCPClosed;}};void Acknowledge(){if(pTCPState->Acknowledge()){delete pTCPState;pTCPState=new TCPEstablishd;}};void SetTCPState(TCPState* tmp){pTCPState=tmp;}TCPState* GetTCPState(){return pTCPState;}};#endif#include "state.h"int main(){TCPConnection example;example.Close();example.Open();example.Open();example.Acknowledge();example.Open();example.Close();return 0;}