設計模式(十七)——狀態變化模式-state

對象模式所屬類別簡介

狀態變化模式包括: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;
}

//效果與設計一一樣,不過此版本無法直接編譯,要分開文件寫,因爲調用順序導致無法編譯通過。

設計二更改版本

設計二比設計一區別
一個是狀態轉換,一個是狀態對象的轉換,狀態對象轉換比較靈活。增加狀態的話只要增加狀態對象,其他可不用修改。

模式定義

允許一個對象在其內部狀態改變時改變它的行爲,從而使其看起來似乎修改了其行爲。

模式結構

在這裏插入圖片描述

要點總結

實現了具體操作和狀態轉換之間的解耦合。
一般可以用單例模式共享一個實例對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章