直接上代码:
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、状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。