接下來建立 enum 列舉描述有哪些狀態
enum VendingState {
Vending,
SoldOut,
InsertingCoins
}
接下來建立一個變數, 設定目前的狀態
class VendingMachine {
private _state: VendingState = VendingState.Vending;
}
再將所有公開方法(function) 依照這個狀態做改變行為
insertMoney(money: number): number {
if( this._state == VendingState.Vending ) {
...
} else if ( this._state == VendingState.SoldOut ) {
...
} else {
...
}
就像上面, 我們先把所有公開方法(function) 按照if-else 判斷在每一個狀態中, 只考慮自己本身的方法行為是甚麼. 不用考慮其他公開方法(function) 的行為.
例如投幣的方法insertMoney 我們可以把這個方法寫成
insertMoney(money: number): number {
if( this._state == VendingState.SoldOut ) {
return money;
} else if( this._state == VendingState.Vending ) {
this._amount = money;
if( this._amount >= this._price ){
this.vendingLed = true;
this.ledScreen = `已投${this._amount} 元, 請按下購買`;
} else {
this.ledScreen = `已投${this._amount} 元, 請繼續投幣`;
}
this._state = VendingState.InsertingCoins;
return 0;
} else if( this._state == VendingState.InsertingCoins ) {
if( this._amount >= this._price ){
this.vendingLed = true;
this.ledScreen = `已投${this._amount} 元, 請按下購買`;
return money;
} else {
this.vendingLed = false;
this._amount += money;
this.ledScreen = `已投${this._amount} 元, 請繼續投幣`;
return 0;
}
}
}
投幣的行為會因為每一個狀態不同所對應的處理動作也不同, 上面程式碼寫出
接下來我們來實踐buyButton 方法, 同樣地buyButton 方法中也針對每一個狀態進行不同所對應的處理動作.
buyButton(): [boolean, number] {
if( this._state == VendingState.SoldOut ) {
return [false, 0];
} else if( this._state == VendingState.Vending ) {
return [false, 0];
} else if( this._state == VendingState.InsertingCoins ) {
if( this._amount >= this._price ){
let refund = this._amount - this._price;
this._state = VendingState.Vending;
return [true, refund];
} else {
return [false, 0];
}
}
}
取消購買方法也按照這模式修改
cancel(): number {
if( this._state == VendingState.SoldOut ) {
return 0;
} else if( this._state == VendingState.Vending ) {
return 0;
} else if( this._state == VendingState.InsertingCoins ) {
if( this._inventory > 0 ) {
this.ledScreen = `庫存${this._inventory} 瓶, 請投幣購買`;
this._state = VendingState.Vending
} else {
this.ledScreen = `飲料已售完`;
this._state = VendingState.SoldOut;
}
let refund = this._amount;
this._amount = 0;
return refund;
}
}
好, 先不管程式碼邏輯到底有沒有正確, 觀察以上程式碼, 我們可以看到這幾個公開方法(function) 裡面都有針對每一種狀態做不同處理的動作.
下一步我們要消滅許多if-else , 之前有提到過如何消滅if-else 方法. 所以我們要定義一個抽象類別(Class) , 在這個抽象類別內, 每個動作都有一個對應的方法.