天天看點

Java設計模式之狀态模式

狀态模式定義,允許對象在自己内部狀态改變時改變它的行為,對象看起來就像是修改了它的類。

該描述第一部分意思是,這個模式将狀态封裝進了一個獨立的類,并将動作委托到對象的目前狀态的狀态對象。第二個部分意思就是,讓客戶感覺使用了對象能夠改變它的行為,但是實際上這種設計模式 使用組合通過簡單引用不同狀态對象來造成類的改變假象。狀态模式封裝了一組行為。

狀态模式類圖

Context:是一個上下文類,可以擁有一些内部狀态,并且将多個狀态對象組合結合在一起。

State接口:定義了所有狀态具有的共同操作,一般可以将該接口的方法和context設定一樣的。

ConcreteStateA:實作了具體的狀态對象,處理來自context的請求,凡是context中調用request方法,都會将該方法委托到具體的狀态對象來處理。

通過在context來利用組合和多态,進而在實際的狀态改變中将行為委托到具體的實作狀态類中,狀态模式将每一個狀态的行為具體到局部化到該狀态所對象的類中,免去了大量的if判斷,它可以讓每一個狀态“對修改關閉”,讓context“對擴充開放”。

一般來說,當狀态轉換是固定的時候,一般将狀态的改變放置到context中。當轉換是動态的時候,則将狀态的改變放置到狀态類中,狀态類中應該有context的引用。

執行個體代碼

一個糖果機,有四種不同的狀态,根據不同的行為就會轉換成不同的狀态。

狀态State接口

package com.whut.state;

publicinterface State {

void insertQuarter();

void ejectQuarter();

void turnCrank();

void dispense();

}

糖果機類(context)

//狀态模式

public class GumballMachine {

private State soleOutState;

private State noQuarterState;

private State hasQuarterState;

private State soldState;

private State winnerState;

private State state=soleOutState;

private int count=0;

public GumballMachine(int count)

{

soleOutState=new SoldOutState(this);

noQuarterState=new NoQuarterState(this);

hasQuarterState=new HasQuarterState(this);

soldState=new SoldState(this);

winnerState=new WinnerState(this);

this.count=count;

if(count>0)

state=noQuarterState;

//投入25分的動作

public void insertQuarter()

state.insertQuarter();

//退回25分的動作

public void ejectQuarter()

state.ejectQuarter();

//轉動曲柄

public void turnCrank()

state.turnCrank();

state.dispense();

//釋放糖果

public void releaseBall()

System.out.println("A gunmball comes rolling out the slot from machine");

if(count!=0)

count=count-1;

//列印機器目前狀态

@Override

public String toString()

return"-----------"+"\nThe machine state:"+state.toString()+"\ncount="+count+"\n-----------";

//設定狀态

publicvoid setState(State st)

this.state=st;

//擷取狀态

public State getSoleOutState() {

return soleOutState;

public State getNoQuarterState() {

return noQuarterState;

public State getHasQuarterState() {

return hasQuarterState;

public State getSoldState() {

return soldState;

//擷取總的數目

publicint getCount() {

return count;

public State getWinnerState() {

return winnerState;

狀态實作類:

public class NoQuarterState implements State {

private GumballMachine gumballMachine;

public NoQuarterState(GumballMachine gumballMachine)

this.gumballMachine=gumballMachine;

publicvoid insertQuarter() {

System.out.println("You inserted a quarter");

gumballMachine.setState(gumballMachine.getHasQuarterState());

publicvoid ejectQuarter() {

System.out.println("You haven't inserted a quarter");

publicvoid turnCrank() {

System.out.println("You turned,but there's no quarter");

publicvoid dispense() {

System.out.println("You need to pay a quarter first");

狀态模式與政策模式比較

狀态模式,将一群行為封裝到狀态對象中,Context的行為随時可委托到那些狀态對象中的一個。對象的狀态改變是在内部實作的,遊走于對象集合中,使用者察覺不到,隻是通過觸發相應的行為。狀态模式利用許多個不同的狀态對象作為其成員屬性進行組合,任何狀态的改變都是事先定義好的。

政策模式,客戶往往是主動指定Context所要組合的政策對象是哪一個,使得能夠在運作的時候改變政策即對象的行為。可以将狀态模式想成是不用在context中放置許多條件判斷語句的替代方法,通過将行為包裝進狀态對象後,可以通過在context内部來改變狀态對象來改變context的行為。政策模式通常是利用行為或者政策類來配置context類的。

本文轉自 zhao_xiao_long 51CTO部落格,原文連結:http://blog.51cto.com/computerdragon/1177995