//狀態接口
public interface State {
public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense();
}
//實現狀態接口
public class NoQuarterState implements State {
GumballMachine gumballMachine;
//通過構造器,得到糖果機的引用
public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
public void insertQuarter() {
System.out.println("You inserted a quarter");
gumballMachine.setState(gumballMachine.getHasQuarterState());
}
public void ejectQuarter() {
System.out.println("You haven't inserted a quarter");
}
public void turnCrank() {
System.out.println("You turned, but there's no quarter");
}
public void dispense() {
System.out.println("You need to pay first");
}
public String toString() {
return "waiting for quarter";
}
}
public class HasQuarterState implements State {
//添加一個隨機數產生器
Random randomWinner = new Random(System.currentTimeMillis());
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
public void insertQuarter() {
System.out.println("You can't insert another quarter");
}
public void ejectQuarter() {
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
public void turnCrank() {
System.out.println("You turned...");
//決定這名顧客是否贏了
int winner = randomWinner.nextInt(10);
if ((winner == 0) && (gumballMachine.getCount() > 1)) {
gumballMachine.setState(gumballMachine.getWinnerState());
} else {
gumballMachine.setState(gumballMachine.getSoldState());
}
}
public void dispense() {
System.out.println("No gumball dispensed");
}
public String toString() {
return "waiting for turn of crank";
}
}
//實現糖果機
public class GumballMachine {
//所有的狀態都在這裏
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState;
State state = soldOutState;
int count = 0;
public GumballMachine(int numberGumballs) {
//每種狀態創建一個狀態實例
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
winnerState = new WinnerState(this);
this.count = numberGumballs;
if (numberGumballs > 0) {
state = noQuarterState;
}
}
public void insertQuarter() {
state.insertQuarter();
}
public void ejectQuarter() {
state.ejectQuarter();
}
public void turnCrank() {
state.turnCrank();
state.dispense();
}
void setState(State state) {
this.state = state;
}
void releaseBall() {
System.out.println("A gumball comes rolling out the slot...");
if (count != 0) {
count = count - 1;
}
}
int getCount() {
return count;
}
void refill(int count) {
this.count = count;
state = noQuarterState;
}
public State getState() {
return state;
}
public State getSoldOutState() {
return soldOutState;
}
public State getNoQuarterState() {
return noQuarterState;
}
public State getHasQuarterState() {
return hasQuarterState;
}
public State getSoldState() {
return soldState;
}
public State getWinnerState() {
return winnerState;
}
public String toString() {
StringBuffer result = new StringBuffer();
result.append("\nMighty Gumball, Inc.");
result.append("\nJava-enabled Standing Gumball Model #2004");
result.append("\nInventory: " + count + " gumball");
if (count != 1) {
result.append("s");
}
result.append("\n");
result.append("Machine is " + state + "\n");
return result.toString();
}
}
package net.dp.state.gumballstatewinner;
public class GumballMachineTestDrive {
public static void main(String[] args) {
GumballMachine gumballMachine =
new GumballMachine(10);
System.out.println(gumballMachine);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
//再在轉動執行多次
}
}
《Head First 設計模式》學習筆記——狀態模式
在軟件開發過程中,應用程序可能會根據不同的情況作出不同的處理。最直接的解決方案是將這些所有可能發生的情況全都考慮到。然後使用if... ellse語句來做狀態判斷來進行不同情況的處理。但是對複雜狀態的判斷就顯得“力不從心了”。隨着增加新的狀態或者修改一個狀體(if else(或switch case)語句的增多或者修改)可能會引起很大的修改,而程序的可讀性,擴展性也會變得很弱。維護也會很麻煩。那麼我就考慮只修改自身狀態的模式。————題記
設計模式
狀態模式:允許對象在內部狀態改變時改變他的行爲,對象看起來好像修改了它的類。
這個模式將狀態封裝稱爲獨立的類,並將動作委託到代表當前狀態的對象,我們知道行爲會隨着內部狀態而改變。
設計原則
封裝變化
多用組合,少用繼承
針對接口編程,不針對實現編程
爲交互對象之間松耦合設計而努力
類應該對擴展開發,對修改關閉
依賴抽象,不依賴具體類
只和朋友交談
別找我,我會找你
類應該只有一個改變的理由
要點
狀態模式允許一個對象基於內部狀態而擁有不同的行爲。
和程序狀態機不同,狀態模式用類代表狀態。
策略模式通常會用行爲或算法來配置context類,狀態模式允許context隨着狀態改變而改變行爲,狀態轉變可以由state類或context類控制。
使用狀態模式會導致設計模式中類的數目大量增加。
狀態類可以被多個context共享。
模型匹配
狀態模型 封裝基於狀態的行爲,並將行爲委託到當前狀態
策略模型 將可以互換的行爲封裝起來,然後使用委託的方法,決定使用哪一個行爲。
模板方法模型 由子類決定實現算法的某些步驟
何時使用?
State模式在實際使用中比較多,適合"狀態的切換".因爲我們經常會使用If elseif else 進行狀態切換, 如果針對狀態的這樣判斷切換反覆出現,我們就要聯想到是否可以採取State模式了.
不只是根據狀態,也有根據屬性.如果某個對象的屬性不同,對象的行爲就不一樣,這點在數據庫系統中出現頻率比較高,我們經常會在一個數據表的尾部,加上property屬性含義的字段,用以標識記錄中一些特殊性質的記錄,這種屬性的改變(切換)又是隨時可能發生的,就有可能要使用State.
狀態模式:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.