經過轉接器模式後,先快轉進入到第十章─ 狀態模式。
本章的舉例是目前有一台糖果機,想要設計一套軟體讓糖果機變成由軟體控制,要求包含在"投入25美分"後可以選擇"轉動旋鈕"來"售出糖果",或"退出25美分";另外還會檢查糖果機目前的糖果剩餘數量是否可以繼續營業或需要轉為"糖果售罄"狀態。
首先,就從狀態圖轉為程式碼─ 實作狀態機開始。步驟如下:
const static int SOLD_OUT = 0;
const static int NO_QUARTER = 1;
const static int HAS_QUARTER = 2;
const static int SOLD = 3;
int state = SOLD_OUT;
void insertQuarter()
{
if (state == HAS_QUARTER)
{
cout << "You can't insert another quarter!" << endl;
}
else if (state == NO_QUARTER)
{
state = HAS_QUARTER;
cout << "You inserted a quarter!" << endl;
}
else if (state ==SOLD_OUT)
{
cout << "You can't insert a quarter! The machine is sold out!" << endl;
}
else if (state ==SOLD)
{
cout << "Please wait! Gumball coming!" << endl;
}
}
而組織起來,整個糖果機的實作大致如下;我們把轉動旋鈕這個方法也放進去。
class GumballMachine
{
const static int SOLD_OUT = 0;
const static int NO_QUARTER = 1;
const static int HAS_QUARTER = 2;
const static int SOLD = 3;
int m_state = SOLD_OUT;
int m_count = 0; // for gumball count
public:
GumballMachine(int count)
{
m_count = count;
if(count > 0)
{
m_state = NO_QUARTER;
}
}
void insertQuarter()
{
if (m_state == HAS_QUARTER)
{
cout << "You can't insert another quarter!" << endl;
}
else if (m_state == NO_QUARTER)
{
m_state = HAS_QUARTER;
cout << "You inserted a quarter!" << endl;
}
else if (m_state == SOLD_OUT)
{
cout << "You can't insert a quarter! The machine is sold out!" << endl;
}
else if (m_state == SOLD)
{
cout << "Please wait! Gumball coming!" << endl;
}
}
void turnCrank()
{
if (m_state == HAS_QUARTER)
{
cout << "You turned..." << endl;
m_state = SOLD;
dispense(); // 掉出糖果的方法,一樣在另一個方法中實作
}
else if (m_state == NO_QUARTER)
{
cout << "You turned but there's no quarter!" << endl;
}
else if (m_state == SOLD_OUT)
{
cout << "You turned but there's no gumball!" << endl;
}
else if (m_state == SOLD)
{
cout << "You turned twice!" << endl;
}
}
};
可以試著自行完成ejectQuarter()
(退回25美分)與dispense()
(掉出糖果)兩個方法,並實際操作看看輸出是否符合預期!
GumballMachine *machine = new GumballMachine(10);
machine->insertQuarter();
machine->turnCrank();
/*-----output-----*/
此時出現了一個變動... 糖果機廠商希望增加一個特殊條件,當轉動旋鈕時,有10%的機率會掉出2顆糖果!此時狀態機肯定也要進行修改,變成如下的狀態圖,那程式要怎麼做相應的修改呢?