狀態(tài)模式把所研究的對象的行為包裝在不同的狀態(tài)對象里,每一個狀態(tài)對象都屬于一個抽象狀態(tài)類的一個子類。通過改變對象內(nèi)部的狀態(tài),使得你可以在運(yùn)行時動態(tài)改變一個對象的行為。

狀態(tài)模式的示意性類圖
首先我們設(shè)定一個奧特曼的接口
interface Ultraman {
void attackMonster();
void shapeShift();
void shooting();
void usePower();
}
這個奧特曼有3種狀態(tài):
/**人類狀態(tài)**/
public class personState implements Ultraman {
private Context context;
personState(Context context){
System.out.println("我是一個人 !!");
this.context=context;
}
@Override
public void attackMonster(){
System.out.println("人類打不贏怪獸,快變身吧");
}
@Override
public void shapeShift(){
System.out.println("變成奧特曼了");
context.setState(context.becomeUltraman());
}
@Override
public void shooting(){
System.out.println("射擊??!");
}
@Override
public void usePower() {
//do nothing
}
}
/**力量用完的狀態(tài)**/
class powerOffState implements Ultraman {
private Context context;
powerOffState(Context context) {
this.context = context;
}
@Override
public void attackMonster() {
}
@Override
public void shapeShift() {
System.out.println("變成人了");
context.setState(context.becomePeople());
}
@Override
public void shooting() {
System.out.println("手太大,射擊技能不能使用");
}
@Override
public void usePower() {
System.out.println("能量用完了");
}
}
/**正常奧特曼狀態(tài)**/
public class ultramanState implements Ultraman {
private Context context;
ultramanState(Context context) {
this.context = context;
}
@Override
public void attackMonster() {
System.out.println("攻擊小怪獸");
context.resultMonster();
}
@Override
public void shapeShift() {
System.out.println("變成人了");
context.setState(context.becomePeople());
}
@Override
public void shooting() {
System.out.print("手太大,射擊技能不能使用");
}
@Override
public void usePower() {
System.out.println("消耗能量一顆");
}
}
這是一個環(huán)境角色部分,定義用戶需要或者說感興趣的接口
public class Context {
private Ultraman personState;
private Ultraman powerOffState;
private Ultraman ultramanState;
private Ultraman ultraman;
private int powerValue;
public Context() {
this.personState = new personState(this);
this.powerOffState = new powerOffState(this);
this.ultramanState = new ultramanState(this);
this.ultraman = personState;
}
//設(shè)置當(dāng)前處于的狀態(tài)
void setState(Ultraman ultraman) {
this.ultraman = ultraman;
}
//變身 變身前初始化能量
public void shapeShift(int powerValue) {
this.powerValue = powerValue;
ultraman.shapeShift();
}
//變成人
Ultraman becomePeople() {
return personState;
}
//變成怪獸
Ultraman becomeUltraman() {
return ultramanState;
}
//打怪獸的結(jié)果
void resultMonster() {
if (powerValue > 0) { //能量沒有用完
ultraman.usePower();
System.out.println("哈哈哈 恭喜擊敗小怪獸1只");
powerValue--;
} else {
//能量用完轉(zhuǎn)化成能量用完狀態(tài)
this.setState(powerOffState);
ultraman.usePower();
System.out.println("你被小怪獸擊敗了");
}
}
//攻擊怪獸
public void battle() {
ultraman.attackMonster();
}
//射擊
public void shooting() {
ultraman.shooting();
}
}
實際調(diào)用部分
public class battleTest {
public static void main(String[] args){
int powerValue=1; //初始化奧特曼的能量為5
Context context=new Context();
System.out.println("怪獸出現(xiàn)了0口0");
context.shooting(); //人類可以射擊
context.battle(); //人類可以射擊
context.shapeShift(powerValue); //射擊不成功,變身
for(int i=0;i<1;i++){ //出現(xiàn)了四只怪獸,打敗了所有怪獸
context.battle();
}
context.shapeShift(powerValue); //打完怪獸,變回人
context.shooting(); //人類可以射擊
context.shapeShift(powerValue); //又變成怪獸
for(int i=0;i<2;i++){ //出現(xiàn)了六只怪獸,被打敗
context.battle();
}
}
}
和策略模式存在的區(qū)別:【自己切換和主動切換】
狀態(tài)模式將各個狀態(tài)所對應(yīng)的操作分離開來,即對于不同的狀態(tài),由不同的子類實現(xiàn)具體操作,不同狀態(tài)的切換由子類實現(xiàn),當(dāng)發(fā)現(xiàn)傳入?yún)?shù)不是自己這個狀態(tài)所對應(yīng)的參數(shù),則自己給Context類切換狀態(tài);而策略模式是直接依賴注入到Context類的參數(shù)進(jìn)行選擇策略,不存在切換狀態(tài)的操作練習(xí)。
在jdk里的應(yīng)用:
java.util.Iterator
javax.faces.lifecycle.LifeCycle#execute()
參考:http://blog.csdn.net/seacean2000/article/details/10528153