直接上代碼:
Before
3-speed ceiling fan state machine
// Not good: unwieldy "case" statement
class CeilingFanPullChain
{
private int m_current_state;
public CeilingFanPullChain()
{
m_current_state = 0;
}
public void pull()
{
if (m_current_state == 0)
{
m_current_state = 1;
System.out.println(" low speed");
}
else if (m_current_state == 1)
{
m_current_state = 2;
System.out.println(" medium speed");
}
else if (m_current_state == 2)
{
m_current_state = 3;
System.out.println(" high speed");
}
else
{
m_current_state = 0;
System.out.println(" turning off");
}
}
}
public class StateDemo
{
public static void main(String[] args)
{
CeilingFanPullChain chain = new CeilingFanPullChain();
while (true)
{
System.out.print("Press ");
get_line();
chain.pull();
}
}
static String get_line()
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in))
;
String line = null;
try
{
line = in.readLine();
}
catch (IOException ex)
{
ex.printStackTrace();
}
return line;
}
}
Output
Press
low speed
Press
medium speed
Press
high speed
Press
turning off
Press
low speed
Press
medium speed
Press
high speed
Press
turning off
After
The CeilingFanPullChain class is now a wrapper' that delegates to its m_current_state reference. Each clause from the "before" case statement is now captured in a State derived class.
For this simple domain, the State pattern is probably over-kill.
class CeilingFanPullChain
{
private State m_current_state;
public CeilingFanPullChain()
{
m_current_state = new Off();
}
public void set_state(State s)
{
m_current_state = s;
}
public void pull()
{
m_current_state.pull(this);
}
}
interface State
{
void pull(CeilingFanPullChain wrapper);
}
class Off implements State
{
public void pull(CeilingFanPullChain wrapper)
{
wrapper.set_state(new Low());
System.out.println(" low speed");
}
}
class Low implements State
{
public void pull(CeilingFanPullChain wrapper)
{
wrapper.set_state(new Medium());
System.out.println(" medium speed");
}
}
class Medium implements State
{
public void pull(CeilingFanPullChain wrapper)
{
wrapper.set_state(new High());
System.out.println(" high speed");
}
}
class High implements State
{
public void pull(CeilingFanPullChain wrapper)
{
wrapper.set_state(new Off());
System.out.println(" turning off");
}
}
public class StateDemo
{
public static void main(String[] args)
{
CeilingFanPullChain chain = new CeilingFanPullChain();
while (true)
{
System.out.print("Press ");
get_line();
chain.pull();
}
}
static String get_line()
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in))
;
String line = null;
try
{
line = in.readLine();
}
catch (IOException ex)
{
ex.printStackTrace();
}
return line;
}
}
State Pattern 主要解決的問(wèn)題是對(duì)象的行為依賴于它的狀態(tài)(屬性),并且可以根據(jù)它的狀態(tài)改變而改變它的相關(guān)行為。
使用場(chǎng)景:1、行為隨狀態(tài)(成員變量)改變而改變的場(chǎng)景。 2、條件、分支語(yǔ)句的代替者。
具體方法:將各種具體的狀態(tài)類抽象出來(lái)。
優(yōu)點(diǎn):自行體會(huì)。
缺點(diǎn):1、狀態(tài)模式的使用必然會(huì)增加系統(tǒng)類和對(duì)象的個(gè)數(shù)。 2、狀態(tài)模式的結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂。 3、狀態(tài)模式對(duì)"開閉原則"的支持并不太好,對(duì)于可以切換狀態(tài)的狀態(tài)模式,增加新的狀態(tài)類需要修改那些負(fù)責(zé)狀態(tài)轉(zhuǎn)換的源代碼,否則無(wú)法切換到新增狀態(tài),而且修改某個(gè)狀態(tài)類的行為也需修改對(duì)應(yīng)類的源代碼。