1. 程式人生 > >軟考設計模式——狀態模式(C++篇)

軟考設計模式——狀態模式(C++篇)

狀態模式顧名思義就是通過改變狀態來控制物件的行為。



設計思路簡而言之,就是有一個物件,這個物件需要一些狀態,用狀態當引數去例項化這個物件,然後根據一些引數的改變,去改變這個物件的狀態,然後讓這個物件根據狀態的不同做不同的行為。



舉個簡單的例子,把一個人(這個人會例項化成一個物件)分為青年,中年,老年三種狀態,在每個年齡階段可以幹不同的事情。


#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;
}