軟考設計模式——狀態模式(C++篇)
阿新 • • 發佈:2018-12-06
狀態模式顧名思義就是通過改變狀態來控制物件的行為。
設計思路簡而言之,就是有一個物件,這個物件需要一些狀態,用狀態當引數去例項化這個物件,然後根據一些引數的改變,去改變這個物件的狀態,然後讓這個物件根據狀態的不同做不同的行為。
舉個簡單的例子,把一個人(這個人會例項化成一個物件)分為青年,中年,老年三種狀態,在每個年齡階段可以幹不同的事情。
#include <iostream> #include <string> using namespace std; class Person; //因為要用到person,所以先宣告一下 class State{ //設定抽象類:狀態類,這個類用來獲取當前人的狀態 public: virtual void young(){} //用了virtual的話,這個State類不能被例項化,他的子類需要過載才能用這個函式 virtual void mid(){} virtual void old(){} virtual void nowState(Person *person){} //nowState就是獲取當前的狀態,每個函式裡要寫這個同名函式覆蓋父類的這個函式 }; class Person{ private: State *state; //宣告一個狀態類的指標,使用指標才能用“->”這個符號來呼叫這個類的函式 int age; //年齡 public: Person(State *state,int age){this->state = state; this->age = age;} //Person的建構函式,初始化時傳入初始的狀態指標和年齡 void setState(State *state){this->state = state;} //設定狀態,設定狀態後,Person的狀態就會改變成相應的狀態 void getState(){state->nowState(this);} //獲得狀態,根據設定好的狀態去呼叫該狀態的nowState方法 void setAge(int age){this->age = age;} //設定年齡 int getAge(){return this->age;} //獲得年齡 };
接下來要分別設定狀態:
class OldMan:public State{ void old(Person *person){ if(person->getAge() > 50){ cout<<"You're old"<<endl; } } void nowState(Person *person){old(person);} //Person裡面的getState方法裡面呼叫的就是這個函式,這個函式又呼叫了自己類的old函式 }; class MidMan:public State{ void mid(Person *person){ if(person->getAge() > 25 && person->getAge()<=50){ cout<<"You're mid"<<endl; }else{ person->setState(new OldMan()); //使用setState方法,然後例項化一個OldMan的指標(new出來的物件,他的型別就是指標)當做引數來更改狀態 } } void nowState(Person *person){mid(person);} }; class Young:public State{ void young(Person *person){ if(person->getAge() <= 25){ cout<<"You're young"<<endl; }else{ person->setState(new MidMan()); } } void nowState(Person *person){young(person);} };
客戶使用:
int main(){ int age=1; Person *person = new Person(new Young(),age); //這裡初始化一個Person物件 for(age = 1;age < 100;age+=9){ cout<<"now_age:"<<age<<endl; person->setAge(age); person->getState(); //通過person物件來獲取狀態,因為狀態會在age變化時改變,具體來說就是getState呼叫了狀態的currentState,然後進入相應的方法去改變狀態 } getchar(); return 0; }