狀態(tài)設(shè)計模式
狀態(tài)模式屬于行為模式绸栅,基于當(dāng)前狀態(tài)處理運行時對象的行為坟桅。
當(dāng)一個對象內(nèi)部狀態(tài)發(fā)生變更時,允許該對象改變其行為丈秩。對象可能會顯示地更改其類。
狀態(tài)設(shè)計模式是怎樣工作的
- 定義一個表示多種狀態(tài)的對象诗箍,該對象可以成為一個記憶狀態(tài)機癣籽。
- 定義一個上下文對象,行為隨其狀態(tài)而變化滤祖。
用例
狀態(tài)模式在游戲開發(fā)中是一種經(jīng)常使用的設(shè)計模式筷狼。
游戲角色體征可能存在不同的狀態(tài)如:健康(綠色、能飛能跑)匠童、虛弱(黃色埂材,能走)、死亡汤求;
當(dāng)體征為健康時俏险,允許角色可以使用不同的武器攻擊敵人严拒。
當(dāng)體征為虛弱時,健康瀕臨一個臨界值竖独。
當(dāng)體征值達(dá)到0時裤唠,即角色死亡游戲結(jié)束。
編碼實現(xiàn)
Player.java
Player 類定義了一個玩家不同的動作莹痢。
package org.byron4j.cookbook.designpattern.state;
public class Player {
public void attack(){
System.out.println("Attack");
}
public void fireBumb() {
System.out.println("Fire Bomb");
}
public void fireGunblade() {
System.out.println("Fire Gunblade");
}
public void fireLaserPistol() {
System.out.println("Laser Pistols");
}
public void firePistol() {
System.out.println("Fire Pistol");
}
public void survive() {
System.out.println("Surviving!");
}
public void dead() {
System.out.println("Dead! Game Over");
}
}
GameComtext.java
定義了不同的動作其條件依賴于player的狀態(tài)种蘸。
package org.byron4j.cookbook.designpattern.state;
public class GameContext {
private Player player = new Player();
public void gameAction(String state) {
if (state == "healthy") {
player.attack();
player.fireBumb();
player.fireGunblade();
player.fireLaserPistol();
} else if (state == "survival") {
player.survive();
player.firePistol();
} else if (state == "dead") {
player.dead();
}
}
}
上面的代碼快照, gameAction 方法包含了很多條件塊去表現(xiàn)不同的動作基于player的當(dāng)前狀態(tài)竞膳。
但是是一堆很難維護(hù)的代碼航瞭。,我們可以使用狀態(tài)模式來避免該問題坦辟。
狀態(tài)設(shè)計模式實例
狀態(tài)模式類圖
需要傳入 Player 類的實例的動作方法
public interface PlayerState {
void action(Player p);
}
2. 定義三個不同的類表示不同的狀態(tài)
均實現(xiàn)了 PlayerState 接口刊侯,提供了指定的 action() 方法的實現(xiàn)。
public class HealthyState implements PlayerState {
@Override
public void action(Player p) {
p.attack();
p.fireBumb();
p.fireGunblade();
p.fireLaserPistol();
}
}
public class SurvivalState implements PlayerState {
@Override
public void action(Player p) {
p.survive();
p.firePistol();
}
}
public class DeadState implements PlayerState {
@Override
public void action(Player p) {
p.dead();
}
}
3. GameContxt 類包含設(shè)置狀態(tài)的方法組合锉走。
public class GameContext {
private PlayerState state = null;
private Player player = new Player();
public void setState(PlayerState state) {
this.state = state;
}
public void gameAction() {
state.action(player);
}
}
設(shè)計模式測試用例
public class GameTest {
public static void main(String[] args) {
GameContext context = new GameContext();
context.setState(new HealthyState());
context.gameAction();
System.out.println("*****");
context.setState(new SurvivalState());
context.gameAction();
System.out.println("*****");
context.setState(new DeadState());
context.gameAction();
System.out.println("*****");
}
}
輸出為:
Attack
Fire Bomb
Fire Gunblade
Laser Pistols
*****
Surviving!
Fire Pistol
*****
Dead! Game Over
*****
Process finished with exit code 0