天天看點

C++設計模式——狀态模式(State)

狀态模式

在軟體建構過程中,某些對象的狀态變化會導緻行為也随之變化。允許一個對象在其内部狀态改變時改變它的行為,使對象看起來似乎修改了其行為。

enum NetworkState{
    Network_Open,
    Network_Close,
    Network_Connect,
};
class NetworkProcessor{
    NetworkState state;
public:
    void Operation1(){
        if (state == Network_Open){
            //**********
            state = Network_Close;
        }
        else if (state == Network_Close){
            //..........
            state = Network_Connect;
        }
        else if (state == Network_Connect){
            //$$$$$$$$$$
            state = Network_Open;
        }
    }
    public void Operation2(){
        if (state == Network_Open){
            //**********
            state = Network_Connect;
        }
        else if (state == Network_Close){
            //.....
            state = Network_Open;
        }
        else if (state == Network_Connect){
            //$$$$$$$$$$
            state = Network_Close;
        }
    }
    public void Operation3(){
    }
};      

從上述代碼可看到,每個方法Operation中,對應狀态的行為是不一樣的,當Operation1中的狀态為Network_Open時,執行完一系列操作後,狀态變為Network_Close;當Operation1方法中的狀态為Network_Open時,執行完一系列操作後,狀态變為Network_Connect,這樣的寫法高度耦合,違背了開閉原則。

#pragma once
#ifndef STATE_H
#define STATE_H
#include<iostream>
using namespace std;

class NetWorkState {
public:
    NetWorkState* pNext;//狀态變更統一
    virtual void Operation1() = 0;
    virtual void Operation2() = 0;
    virtual void Operation3() = 0;
    virtual ~NetWorkState() {}
};

class OpenState :public NetWorkState {
public:
    void Operation1() override;
    void Operation2() override;
    void Operation3() override;
};

class CloseState :public NetWorkState {
public:
    void Operation1() override;
    void Operation2() override;
    void Operation3() override;
};

class ConnectState :public NetWorkState {
public:
    void Operation1() override;
    void Operation2() override;
    void Operation3() override;
};

//開狀态的方法行為
void OpenState::Operation1() {
    cout << "Open state  excute operation1" << endl;
    pNext = new CloseState();
    cout << "Now state is  close" << endl;
}
void OpenState::Operation2()  {
    cout << "Open state  excute operation2" << endl;
    pNext = new ConnectState();
    cout << "Now state is  connect" << endl;
}
void OpenState::Operation3()  {
    cout << "Open state  excute operation3" << endl;
    pNext = new OpenState();
    cout << "Now state is  open" << endl;
}
//關狀态的方法行為
void CloseState::Operation1() {
    cout << "Close state  excute operation1" << endl;
    pNext = new ConnectState();
    cout << "Now state is  connect" << endl;
}
void CloseState::Operation2() {
    cout << "Close state  excute operation2" << endl;
    pNext = new OpenState();
    cout << "Now state is  open" << endl;
}
void CloseState::Operation3() {
    cout << "Close state  excute operation3" << endl;
    pNext = new CloseState();
    cout << "Now state is  close" << endl;
}
//連接配接狀态的方法行為
void ConnectState::Operation1() {
    cout << "Connect state  excute operation1" << endl;
    pNext = new CloseState();
    cout << "Now state is  close" << endl;
}
void ConnectState::Operation2() {
    cout << "Connect state  excute operation2" << endl;
    pNext = new ConnectState();
    cout << "Now state is  connect" << endl;
}
void ConnectState::Operation3() {
    cout << "Connect state  excute operation3" << endl;
    pNext = new OpenState();
    cout << "Now state is  open" << endl;
}
#endif // !STATE_H      
#include<iostream>
#include"state.h"

using namespace std;

class NetWorkProcess {//穩定的,不需要修改
public:
  NetWorkProcess(NetWorkState* state) {
    this->pState = state;
  }
  void Operate1() {
    pState->Operation1();
    pState = pState->pNext;
  }
  void Operate2() {
    pState->Operation2();
    pState = pState->pNext;
  }
  void Operate3() {
    pState->Operation3();
    pState = pState->pNext;
  }
  ~NetWorkProcess() {
    delete pState;
  }
private:
  NetWorkState* pState;
};

int main()
{
  NetWorkProcess* networkPro = new NetWorkProcess(new OpenState());
  networkPro->Operate1();
  networkPro->Operate2();
  networkPro->Operate3();
  delete networkPro;
  return 0;
}      

繼續閱讀