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