策略模式是围绕可以互换的算法来创建的。状态模式是通过改变对象内部的状态来帮助对象控制自己的行为。
状态模式定义
允许对象在内部状态改变时改变它的行为。
这个模式将状态封装成为独立的类,并将动作委托到代表当前状态的对象,行为会随着内部状态的改变而改变。
状态模式的类图:
类图解析:
State:State接口定义了一个所有具体状态的共同接口;任何状态都要实现这个相同的接口,这样一来,状态之间可以互相替换。
ConcreteState:具体状态,处理来自Context的请求。每个ConcreteState都提供了它自己对于请求的实现。所以,当Context改变状态时行为也跟着改变。
Context(上下文):是一个类,它可以拥有一些内部状态。
state.handle():不管在什么时候,只要有人调用Context的request()方法,它就会被委托到具体的状态对象来处理。
虽然类图和策略模式的很像,但是它们的意图是不一样的。以状态模式而言,我们将一群行为封装在状态对象中,context的行为随时可委托到那些状态对象中的一个。而以策略模式而言,客户通常要主动指定Context所要组合的策略对象是哪一个。
状态模式是利用许多不同的状态对象,Context对象会随着时间而改变状态,而任何状态改变都是定义好的。
我们举个三个状态的自动转换吧:就緒》运行》阻塞,就这么一个简单的例子来说明状态模式。
状态接口State:
package state;
public interface State {
void handle();
}
具体状态对象:
ReadyState就緒状态:
package concrete_state;
import client.MyClientContext;
import state.State;
public class ReadyState implements State {
private MyClientContext myClientContext;
public ReadyState(MyClientContext myClientContext) {
this.myClientContext = myClientContext;
}
@Override
public void handle() {
System.out.println("I am waiting for cpu");
myClientContext.setCurrentState(myClientContext.getRunningState()); //就绪进入运行态
}
}
RunningState运行状态
package concrete_state;
import client.MyClientContext;
import state.State;
public class RunningState implements State {
private MyClientContext myClientContext;
public RunningState(MyClientContext myClientContext) {
this.myClientContext = myClientContext;
}
@Override
public void handle() {
System.out.println("I am running now");
myClientContext.setCurrentState(myClientContext.getBlockState()); //就运行态进入阻塞状
}
}
BlockState阻塞状态:
package concrete_state;
import client.MyClientContext;
import state.State;
public class BlockState implements State {
private MyClientContext myClientContext;
public BlockState(MyClientContext myClientContext){
this.myClientContext = myClientContext;
}
@Override
public void handle() {
System.out.println("I am blocked.There is not enough resource for me to use.");
}
}
Context上下文:
package client;
import concrete_state.BlockState;
import concrete_state.ReadyState;
import concrete_state.RunningState;
import state.State;
public class MyClientContext {
private State readyState; //就緒状态
private State runningState; //运行状态
private State blockState;//阻塞状态
private State currentState; //当前状态
public MyClientContext(){
readyState = new ReadyState(this);
runningState = new RunningState(this);
blockState = new BlockState(this);
currentState = readyState;
}
public void request(){
currentState.handle();
}
public State getCurrentState() {
return currentState;
}
public void setCurrentState(State currentState) {
this.currentState = currentState;
}
public State getBlockState() {
return blockState;
}
public void setBlockState(State blockState) {
this.blockState = blockState;
}
public State getRunningState() {
return runningState;
}
public void setRunningState(State runningState) {
this.runningState = runningState;
}
public State getReadyState() {
return readyState;
}
public void setReadyState(State readyState) {
this.readyState = readyState;
}
}
测试
import client.MyClientContext;
public class Main {
public static void main(String[] args) {
MyClientContext myClientContext = new MyClientContext();
myClientContext.request();
myClientContext.request();
myClientContext.request();
}
}
测试结果:
I am waiting for cpu
I am running now
I am blocked.There is not enough resource for me to use.
具体的代码请下载demo来看。