现在我们来学习第三种设计模式行为型的第三类,类的状态中的第二种状态模式,这种模式的使用场景很多,随便举个例子,人在健康的时候,可以吃很多饭,在生病的时候不喜欢吃饭。
1、状态模式
当对象的状态改变时,同时改变其行为。
使用场景:1、行为随状态改变而改变的场景。 2、条件、分支语句的代替者。
在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。
2、举个例子
当用户是饥饿状态时,不想吃东西,当用户健康状态时,想要吃东西。
3、UML
用户有两种状态,饥饿和健康状态。
3、State
public interface State {
public void eat();
}
4、HealthState、SicknessState
public class HealthState implements State{
@Override
public void eat() {
System.out.println("我很健康,我想吃东西");
}
}
public class SicknessState implements State{
@Override
public void eat() {
System.out.println("我生病了,吃个piqun");
}
}
5、Context
public class Context {
private State state;
public Context(State state) {
this.state=state;
}
public void setState(State state) {
this.state = state;
}
public void eat() {
state.eat();
}
}
6、Test
public class Test {
public static void main(String[] args) {
State healthSate = new HealthState();
State sicknessState = new SicknessState();
Context context = new Context(healthSate);
context.eat();
context.setState(sicknessState);
context.eat();
}
}
运行结果如下:
我很健康,我想吃东西
我生病了,吃个piqun
7、状态模式与策略模式
本质上来说,这两种模式的类图是一样的。然后举的例子编码编码模式也是一样的。
状态主体(拥有者)持有状态对象,运行时可以通过动态指定状态对象来改变类的行为。
策略主体持有算法族对象,运行时可以通过动态选择算法族中的算法(策略)来改变类的行为。
也就是说,状态模式与策略模式都支持运行时的多态,并且其实现方式都是组合 + 委托。但是这并不代表这两种模式是相同的,因为它们的目标不同。
状态模式实现了算法流程可变(即状态切换,不同的状态有不同的流程)。
策略模式实现了算法细节可选(即选择算法族内的算法,一个算法族包含多个可选算法)。
大白话来说,我觉得状态模式的状态可能会一直在改变,而策略模式相对于比较稳定。当一个状态的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为时,可以考虑使用状态模式。
总结
例子很简单,我把用户的状态抽取出来解耦合,然后每种状态对应不同的行为。其实我看网上的例子跟我的有点不同,但是我觉得我的也完全符合状态模式的定义:当对象的状态改变时,同时改变其行为。当Context对象的状态State改变时,它吃饭也就变成了想吃和不想吃。所以我觉得应该OK。若有不对的地方,望大家指正出来。