意圖:
允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它的類。
適用壞境:
1) 一個對象的行為取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行為。
2) 一個操作中含有龐大的多分支的條件陳述式,且這些分支依賴於該對象的狀態。這個狀態通常用一個或多個枚舉常量表示。通常, 有多個操作包含這一相同的條件結構。State模式將每一個條件分支放入一個獨立的類中。這使得你可以根據對象自身的情況將對象的狀態作為一個對象,這一對象可以不依賴於其他對象而獨立變化。
結構:
實現:
State.h 檔案
#pragma
once
class
Context;
class
State
{
public:
State(void);
virtual~State(void);
virtualvoid
OperationInterface(Context *con);
virtualvoid
OperationChangeState(Context*con);
protected:
boolChangeState(Context*con,State*st);
};
class
ConcreteStateA:public
State
{
public:
ConcreteStateA();
virtual~ConcreteStateA();
virtualvoid
OperationInterface(Context *con);
virtualvoid
OperationChangeState(Context*con);
protected:
};
class
ConcreteStateB:public
State
{
public:
ConcreteStateB();
virtual~ConcreteStateB();
virtualvoid
OperationInterface(Context *);
virtualvoid
OperationChangeState(Context*);
protected:
};
State.cpp檔案
#include
"StdAfx.h"
#include
"State.h"
#include
"Context.h"
#include
"iostream"
using namespace
std;
State::State(void)
{
}
State::~State(void)
{
}
void
State::OperationInterface(Context*con)
{
cout<<"state::"<<endl;
}
void
State::OperationChangeState(Context*con)
{
}
bool
State::ChangeState(Context*con,State*st)
{
con->ChangeState(st);
returntrue;
}
ConcreteStateA::ConcreteStateA()
{
}
ConcreteStateA::~ConcreteStateA()
{
}
void
ConcreteStateA::OperationInterface(Context*con)
{
cout<<"concreteStateA::operation Interface........"<<endl;
}
void
ConcreteStateA::OperationChangeState(Context*con)
{
OperationInterface(con);
this->ChangeState(con,new
ConcreteStateB());
cout<<"change state to B"<<endl;
}
//
ConcreteStateB::ConcreteStateB()
{
}
ConcreteStateB::~ConcreteStateB()
{
}
void
ConcreteStateB::OperationInterface(Context*con)
{
cout<<"concreteStateB::operation Interface........"<<endl;
}
void
ConcreteStateB::OperationChangeState(Context*con)
{
OperationInterface(con);
this->ChangeState(con,new
ConcreteStateA());
cout<<"change state to A"<<endl;
}
Context.h檔案
#ifndef
_STATE_H
#define
_STATE_H
class
State;
class
Context
{
public:
Context(void);
Context(State *state);
voidOperationInterface();
voidOperationChangeState();
virtual~Context(void);
private:
friendclass
State;
//表明在State類中可以訪問Context類的私人欄位
bool
ChangeState(State*state);
State*_state;
};
#endif
Context.cpp檔案
#include
"StdAfx.h"
#include
"Context.h"
#include
"State.h"
Context::Context(void)
{
}
Context::~Context(void)
{
if(_state!=NULL)
{
delete_state;
_state=NULL;
}
}
Context::Context(State *state)
{
this->_state=state;
}
void
Context::OperationInterface()
{
_state->OperationInterface(this);
}
bool
Context::ChangeState(State*state)
{
this->_state=state;
returntrue;
}
void
Context::OperationChangeState()
{
_state->OperationChangeState(this);
}
主函數:
// StatePatten.cpp : 定義控制台應用程式的進入點。
//
#include
"stdafx.h"
#include
"State.h"
#include
"Context.h"
#include
<iostream>
using namespace
std;
int _tmain(intargc,
_TCHAR*argv[])
{
State*st=new
ConcreteStateA();
Context*con=new
Context(st);
con->OperationInterface();
con->OperationChangeState();
if (con!=NULL)
{
deletecon;
con=NULL;
}
if(st!=NULL)
{
deletest;
st=NULL;
}
return0;
}
代碼說明:
State模式在實現中,有2個關鍵點:
(1) 將State聲明為Context的友元類(friend class),其作用是讓State模式訪問Context的Protected介面ChangeState();
(2) State及其子類中的操作都將Context*傳入作為參數,其主要目的是State類可以通過這個指標調用Context中的方法,這也是State模式和Strategy模式的區別;
State 模式和Strategy模式又很大程度上的相似:它們都有一個 Context 類,都是通過委託(組合)給一個具有多個衍生類別的多態基類實現 Context的演算法邏輯。兩者最大的差別就是State模式中衍生類別持有指向Context對象的引用, 並通過這個引用調用Context中的方法,但在 Strategy 模式中就沒有這種情況。因此可以說一個 State 執行個體同樣是 Strategy 模式的一個執行個體,反之卻不成立。實際上 State 模式和 Strategy 模式的區別還在於它們所關注的點不盡相同:State
模式主要是要適應對象對於狀態改變時的不同處理策略的實現,而 Strategy則主要是具體演算法和實現介面的解耦(coupling)。