状态模式(State Pattern)属于对象行为型模式,其意图是允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
2.状态模式角色
Context:用户对象,拥有一个State类型的成员,以标识对象的当前状态。
State:接口或者基类,封装与Context的特定状态相关的行为。
ConcreteState:接口实现类或子类实现了一个与Context某个状态相关的行为。
3.状态模式深入分析
关系图:
1)Context将于状态相关的请求委托给当前的ConcreteState对象处理。
2)Context可将自身作为一个参数传递给处理该请求的状态对象,这使得状态对象在必要的时候可访问Context
3)Context是客户使用的主要接口,客户可用状态对象来配置一个Context,一旦一个Context配置完毕,它的客户不再需要直接同状态对象打交道。
4) Context或者ConcreteState子类都可以决定哪个状态时另外那个状态的后继者,以及是在何种条件下进行状态转换。
代码示例:
----------------------------------------------------------------------------------------------------------------------
package com.example.state;
public abstract class Time {
public abstract void doSomething(Sister sister);
}
package com.example.state;
public class SevenOclock extends Time{
@Override
public void doSomething(Sister sister) {
// TODO Auto-generated method stub
if(sister.getHour() == 7){
System.out.println("早上好,该中饭了");
}else{
sister.setState(new TwelveOclock());
sister.doSomething();
}
}
}
package com.example.state;
public class TwelveOclock extends Time {
@Override
public void doSomething(Sister sister) {
// TODO Auto-generated method stub
if(sister.getHour() == 12){
System.out.println("中午好,该吃早饭了");
}else{
sister.setState(new SixteenOclock());
sister.doSomething();
}
}
}
package com.example.state;
public class SixteenOclock extends Time {
@Override
public void doSomething(Sister sister) {
// TODO Auto-generated method stub
if(sister.getHour() == 16){
System.out.println("晚上好,该吃晚饭了");
}else{
sister.setState(new Other());
sister.doSomething();
}
}
}
package com.example.state;
public class Other extends Time {
@Override
public void doSomething(Sister sister) {
// TODO Auto-generated method stub
System.out.print("未来无法预测,把握当下");
}
}
package com.example.state;
public class Sister {
private Integer hour;
private Time time;
public Sister(){
time=new SevenOclock();
}
public Integer getHour(){
return hour;
}
public void setHour(Integer hour){
this.hour=hour;
}
public void setState(Time time){
this.time=time;
}
public Time getState(){
return time;
}
public void doSomething(){
time.doSomething(this);
time=new SevenOclock();
}
}
测试代码:
package com.example.test;
import com.example.state.Sister;
public class Test {
public static void main(String[] args){
Sister sis=new Sister();
sis.setHour(7);
sis.doSomething();
sis.setHour(12);
sis.doSomething();
sis.setHour(16);
sis.doSomething();
sis.setHour(20);
sis.doSomething();
}
}
测试结果:
早上好,该吃早饭了
中午好,该吃早饭了
早上好,该吃早饭了
未来无法预测,把握当下
------------------------------------------------
4.状态模式的优点和缺点
优点:状态模式使得代码中复杂的逻辑判断问题得到了解决,具体状态角色将具体状态和其对象的行为封装了起来,使得一个新的状态的添加变得非常简单。
缺点:使用状态模式必须是在有状态切换的情况下,而且使用状态模式也增加了代码的复杂度,使得代码不容易理解。
5.状态模式的使用情况
一般而言,我们使用状态模式是为了解决复杂和易变的条件的判断问题。如果问题本身不复杂或者说问题不是太容易改变,就没有必要使用状态模式。因为,
状态模式本身是复杂的。Activity调用的方法的不同状态就是状态模式的应用。