设计模式——状态模式

219 阅读3分钟

一、概述

状态模式,首先理解什么是状态。生活中有很多状态的例子,比如我们网购订单的状态有已下单、已发货、已签收等等状态;比如手机下载文件的状态有下载中、已暂停、已完成等等状态;在公司请假的状态有已申请、已审核、已完成等状态。状态模式就是根据不同的状态,调用相同方法后会有不同的行为,它的目的就是当状态发生改变后,行为也跟着改变,状态模式也是一种行为型模式。

状态模式也是有3个核心的角色:

  • 抽象状态角色:高度抽象的状态,所有状态的父接口。
  • 具体的状态角色:实现了抽象状态接口,在抽象方法中实现当前状态的逻辑;
  • 上下文角色:封装了一个类来维护当前状态,将与状态相关的操作委托给当前状态角色来处理。

下面我们就以订单的不同状态来做具体的说明。

二、使用

首先是定义抽象状态角色的接口,里面只有一个打印当前状态的方法。

/**
 * 订单状态抽象接口
 */
public interface State {
    void printState();
}

然后是具体的订单状态,都实现了抽象状态接口,在抽象的方法中实现各自的逻辑,这里只是简单打印出了当前的状态。

/**
 * 已支付(已下单)状态
 */
public class PaidState implements State{

    private static final String TAG = "XXX";

    @Override
    public void printState() {
        Log.e(TAG, "已下单");
    }
}
/**
 * 已发货状态
 */
public class ShippedState implements State{

    private static final String TAG = "XXX";

    @Override
    public void printState() {
        Log.e(TAG, "已发货");
    }
}
/**
 * 已签收状态
 */
public class ReceivedState implements State{

    private static final String TAG = "XXX";

    @Override
    public void printState() {
        Log.e(TAG, "已签收");
    }
}
/**
 * 已完成状态
 */
public class FinishedState implements State{

    private static final String TAG = "XXX";

    @Override
    public void printState() {
        Log.e(TAG, "已完成");
    }
}

再就是当前的上下文角色了,会通过设置不同的状态,来模拟状态的改变。

/**
 * 查询订单状态
 */
public class Check {

    public static final PaidState PAID_STATE = new PaidState();
    public static final ShippedState SHIPPED_STATE = new ShippedState();
    public static final ReceivedState RECEIVED_STATE = new ReceivedState();
    public static final FinishedState FINISHED_STATE = new FinishedState();

    //默认初始是已下单状态
    private State state = PAID_STATE;

    public void setState(State state){
        this.state = state;
    }

    //查询订单状态
    public void doCheck(){
        state.printState();
    }
}

最后来进行测试,打印输出如下图。

/**
 * Description: 状态模式
 */
public class StateModeActivity extends Activity {

    private static final String TAG = "XXX";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_state_mode);

        Check check = new Check();
        check.setState(Check.PAID_STATE);
        check.doCheck();

        Log.e(TAG, "-------------------------");
        check.setState(Check.RECEIVED_STATE);
        check.doCheck();

        Log.e(TAG, "-------------------------");
        check.setState(Check.FINISHED_STATE);
        check.doCheck();
    }
}

三、总结

从上面的代码结构中,可以看出来状态模式和策略模式基本上是大同小异的,虽然代码上差异很小,最主要的区别在于思想上的不同,策略模式是根据不同的策略来调用不同的算法;而状态模式是根据不同的状态来做出不同的行为。并且策略模式是不会明确的告诉客户端所选择的是哪种策略;而状态模式是会明确的告知客户端的当前状态。

github地址:github.com/leewell5717…

四、参考

Java 中的模式 --- 简单的状态模式