直接上代碼:
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 主要解決的問題是對象的行為依賴于它的狀態(屬性),并且可以根據它的狀態改變而改變它的相關行為。
使用場景:1、行為隨狀態(成員變量)改變而改變的場景。 2、條件、分支語句的代替者。
具體方法:將各種具體的狀態類抽象出來。
優點:自行體會。
缺點:1、狀態模式的使用必然會增加系統類和對象的個數。 2、狀態模式的結構與實現都較為復雜,如果使用不當將導致程序結構和代碼的混亂。 3、狀態模式對"開閉原則"的支持并不太好,對于可以切換狀態的狀態模式,增加新的狀態類需要修改那些負責狀態轉換的源代碼,否則無法切換到新增狀態,而且修改某個狀態類的行為也需修改對應類的源代碼。