狀態模式:當對象狀態改變時行爲也隨之改變,看起來就像是這個類發生了改變。html
首先對象有狀態,行爲由狀態決定。ide
假設如今有一個遊戲角色,有正常狀態、加速狀態、減速狀態、眩暈狀態。this
遊戲角色不一樣狀態下的行爲是不一樣的,減速跑的慢一些、眩暈不能跑。spa
咱們將遊戲角色轉換爲代碼,先看不使用狀態模式的狀況。code
遊戲角色類htm
public class Hero { public static final int COMMON = 1;//正常狀態 public static final int SPEED_UP = 2;//加速狀態 public static final int SPEED_DOWN = 3;//減速狀態 public static final int SWIM = 4;//眩暈狀態 private int state = COMMON;//默認是正常狀態 public int getState() { return state; } public void setState(int state) { this.state = state; } public void run() { if(state == COMMON) { System.out.println("正常狀態"); }else if(state == SPEED_UP) { System.out.println("加速狀態"); } else if(state == SPEED_DOWN) { System.out.println("減速狀態"); } else if(state == SWIM) { System.out.println("眩暈狀態"); } } }
Main對象
public class Main { public static void main(String[] args) { //默認正常狀態 Hero hcf = new Hero(); hcf.run(); //加速狀態 hcf.setState(Hero.SPEED_UP); hcf.run(); //眩暈狀態 hcf.setState(Hero.SWIM); hcf.run(); //減速狀態 hcf.setState(Hero.SPEED_DOWN); hcf.run(); } }
運行結果:
正常狀態
加速狀態
眩暈狀態
減速狀態
遊戲角色中有狀態,執行run方法時會根據狀態打印出不用的結果,即對象狀態的改變也會形成行爲的改變。blog
這樣實現也能夠,但若是後續分支狀態過多,須要大量的if else,並且Hero的狀態只對象Hero有效,怪獸一樣有這些狀態,接口
這些狀態沒法複用。遊戲
這時咱們就能夠採用狀態模式
首先須要將狀態抽取出來,每個狀態對應一個狀態類
狀態接口
public interface State { public void change(Hero hero); }
加速狀態
public class SpeedUpState implements State { @Override public void change(Hero hero) {//傳遞英雄對象,改變英雄對象的狀態 // TODO Auto-generated method stub hero.setState(this); } @Override public String toString() { return "加速狀態"; } }
減速狀態
public class SpeedDownState implements State { @Override public void change(Hero hero) {//傳遞英雄對象,改變英雄對象的狀態 // TODO Auto-generated method stub hero.setState(this); } @Override public String toString() { return "減速狀態"; } }
眩暈狀態
public class SwimState implements State{ @Override public void change(Hero hero) {//傳遞英雄對象,改變英雄對象的狀態 // TODO Auto-generated method stub hero.setState(this); } @Override public String toString() { return "眩暈狀態"; } }
正常狀態
public class CommonState implements State{ @Override public void change(Hero hero) {//傳遞英雄對象,改變英雄對象的狀態 // TODO Auto-generated method stub hero.setState(this); } @Override public String toString() { return "正常狀態"; } }
每個狀態對應一個狀態類,當英雄狀態須要發送變化時,只需建立狀態類,而後將heroz做爲參數,調用狀態類的change方法。
change方法會將當前狀態對象設置到hero中的state屬性,後續直接獲取英雄狀態便可。
Main
public class Main { public static void main(String[] args) { Hero hcf = new Hero(); //正常狀態 CommonState commonState = new CommonState(); commonState.change(hcf); System.out.println(hcf.getState().toString()); //加速狀態 SpeedUpState speedUpState = new SpeedUpState(); speedUpState.change(hcf); System.out.println(hcf.getState().toString()); //眩暈狀態 SwimState swimState = new SwimState(); swimState.change(hcf); System.out.println(hcf.getState().toString()); //減速狀態 SpeedDownState speedDownState = new SpeedDownState(); speedDownState.change(hcf); System.out.println(hcf.getState().toString()); } }
運行結果:
正常狀態
加速狀態
眩暈狀態
減速狀態
後續還有新的狀態只需添加狀態類便可,並且能夠進一步抽象,使Heor類和怪獸類實現同一個接口,這樣這些狀態對於Hero和怪獸都適用。
參考資料: