State狀態模式
(一)概念
允許一個對象在其內部狀態改變時改變它的行爲。對象看起來似乎修改了它的類
狀態模式主要解決的是當控制一個對象狀態的條件表達式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把複雜的判斷邏輯簡化。
狀態模式的主要解決的是,當控制一個對象狀態轉換的條件表達式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以把複雜的判斷邏輯簡化。當然,如果這個狀態判斷邏輯很簡單,就沒有必要使用狀態模式了,Switch/Case可能就可以搞定了。
(二)動機
在軟件構建過程中,某些對象的狀態如果改變,其行爲也會隨之而發生變化,比如文檔處於只讀狀態,其支持的行爲和讀寫狀態支持的行爲就可能會完全不同。
如何在運行時根據對象的狀態來透明地更改對象的行爲?而不會爲對象操作和狀態轉化之間引入緊耦合?
我們將狀態邏輯和動態實現進行分離操作
(三)代碼
state.h
#ifndef STATE_H_
#define STATE_H_
#include<iostream>
class Context;
//抽象狀態類
class State{
public:
virtual void handle(Context* pContext) = 0;
~State() = default;
protected:
State(){}
};
//Contexte類要維護一個具體state類的實例,這個實例保存當前的狀態
class Context{
private:
State* state;
public:
Context(State* state):state(state){};
//請求當前狀態
void Request();
//改變狀態
void ChangeState(State* state);
};
class StateA : public State{
public:
StateA(){};
~StateA() = default;
virtual void handle(Context* pContext);
};
class StateB : public State{
public:
StateB(){};
~StateB() = default;
virtual void handle(Context* pContext);
};
class StateC : public State{
public:
StateC(){};
~StateC() = default;
virtual void handle(Context* pContext);
};
#endif
state.cpp:
#include "state.h"
void Context::Request()
{
state->handle(this);
}
void Context::ChangeState(State* state)
{
this->state = state;
}
void StateA::handle(Context* pContext)
{
std::cout << "StateA";
std::cout << " 改變狀態爲B " << std::endl;
pContext->ChangeState(new StateB());
}
void StateB::handle(Context* pContext)
//執行該狀態的行爲並改變狀態
{
std::cout << "StateB";
std::cout << " 改變狀態爲C " << std::endl;
pContext->ChangeState(new StateC());
}
void StateC::handle(Context* pContext)
{
std::cout << "StateC";
std::cout << " 改變狀態爲A " << std::endl;
pContext->ChangeState(new StateA());
}
main.cpp
#include<iostream>
#include"src/state.h"
using namespace std;
int main()
{
State* pState = new StateA();
Context* pContext = new Context(pState);
pContext->Request();
pContext->Request();
pContext->Request();
pContext->Request();
pContext->Request();
return 0;
}