策略模式是围绕可以互换的算法来创建的。状态模式是通过改变对象内部的状态来帮助对象控制自己的行为。

状态模式定义

允许对象在内部状态改变时改变它的行为。

这个模式将状态封装成为独立的类,并将动作委托到代表当前状态的对象,行为会随着内部状态的改变而改变。

状态模式的类图:
设计模式——状态模式
类图解析:
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来看。

demo代码地址

相关文章: