對象模式所屬類別簡介
狀態變化模式包括:state和memento(備忘錄)。
在組件構建過程中,某些對象的狀態經常面臨變化,如何對這些變化進行有效的管理,又同事維持高層模塊的穩定?
當前模式簡介動機
軟件構建過程中,某些對象狀態如果改變,其行爲也會發生變化。比如文檔處於只讀狀態,其支持的讀寫狀態是不一樣的。
需求
有個程序,有三種狀態開啓,連接、關閉。該程序有兩個操作,操作1在狀態爲開啓的時候把狀態改爲關閉,在狀態爲連接的時候改爲開啓,在狀態爲關閉的時候改爲連接。
操作2在狀態爲開啓的時候改爲連接,在狀態爲連接的時候改爲關閉,在狀態爲關閉的時候改爲開啓。
設計一
#include "stdafx.h"
#include <iostream>
using namespace std;
enum NetWorkState
{
START,
CONNECT,
STOP
};
class CNetWorkOperator
{
public:
NetWorkState m_state;
CNetWorkOperator():m_state(STOP){}
void Func1()
{
if (m_state == START)
{
m_state = STOP;
}
else if (m_state == STOP)
{
m_state = CONNECT;
}
else
{
m_state = START;
}
}
void Func2()
{
if (m_state == START)
{
m_state = CONNECT;
}
else if (m_state == STOP)
{
m_state = START;
}
else
{
m_state = STOP;
}
}
void PrintState()
{
std::cout << "state==" << m_state << std::endl;
}
};
int main()
{
CNetWorkOperator p;
p.Func1();
p.PrintState();
return 0;
}
//打印
state==1
需求更改
設計一更改版
違反原則
1.違反設計模式原則2開放閉合原則。NetWorkState m_state;太唯一,修改不方便。
設計二
#include "stdafx.h"
#include <iostream>
using namespace std;
class INetWorkState
{
public:
INetWorkState *m_pNext;
virtual void Func1()=0;
virtual void Func2()=0;
};
class CCloseState: public INetWorkState
{
public:
static INetWorkState *GetInstant()
{
if (m_pInstant != NULL)
{
m_pInstant = new COpenState();
}
return m_pInstant;
}
void Func1()
{
m_pNext = COpenState::GetInstant();
}
void Func2()
{
m_pNext = CCloseState::GetInstant();
}
private:
static INetWorkState *m_pInstant;
};
class CConnectState: public INetWorkState
{
public:
static INetWorkState *GetInstant()
{
if (m_pInstant != NULL)
{
m_pInstant = new COpenState();
}
return m_pInstant;
}
void Func1()
{
m_pNext = COpenState::GetInstant();
}
void Func2()
{
m_pNext = CCloseState::GetInstant();
}
private:
static INetWorkState *m_pInstant;
};
class COpenState: public INetWorkState
{
public:
static INetWorkState *GetInstant()
{
if (m_pInstant != NULL)
{
m_pInstant = new COpenState();
}
return m_pInstant;
}
void Func1()
{
m_pNext = CCloseState::GetInstant();
}
void Func2()
{
m_pNext = CConnectState::GetInstant();
}
private:
static INetWorkState *m_pInstant;
};
class NetworkProcessor{
INetWorkState* pState;
public:
NetworkProcessor(INetWorkState* pState){
this->pState = pState;
}
void Operation1(){
pState->Func1();
pState = pState->m_pNext;
}
void Operation2(){
pState->Func2();
pState = pState->m_pNext;
}
};
int main()
{
return 0;
}
//效果與設計一一樣,不過此版本無法直接編譯,要分開文件寫,因爲調用順序導致無法編譯通過。
設計二更改版本
設計二比設計一區別
一個是狀態轉換,一個是狀態對象的轉換,狀態對象轉換比較靈活。增加狀態的話只要增加狀態對象,其他可不用修改。
模式定義
允許一個對象在其內部狀態改變時改變它的行爲,從而使其看起來似乎修改了其行爲。
模式結構
要點總結
實現了具體操作和狀態轉換之間的解耦合。
一般可以用單例模式共享一個實例對象。