定义
状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式。
状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。
使用场景
- 一个对象的行为取决与它的状态,而且它必须在运行时根据状态改边他的行为
- 代码中包含大量与对象有关的条件语句,比如,在一个方法中含有多重的判断语句(if-else或者switch-case),并且这些分支依赖这个对象的状态
结构与UML图
角色介绍:
- Context:环境类,定义用户感兴趣的接口吗,维护一个State子类的实例,这个实例定义了当前的状态。
- State:抽象状态类或者接口,定义一个或者一组接口,表示某种状态下的行为
- ConcreteState:具体状态类,每一个具体的状态类实现抽象State中定义的接口,从而达到不同状态下的不同行为
简单事例
这里以wifi连接来简单的演示一下:
环境类:
public class Context {
//维护一个State子类的实例,这个实例定义了当前的状态
private State state;
public void setState(State state) {
this.state = state;
}
/**
* 用户感兴趣的接口方法
*/
public void powerOn(){
state.connect();
}
public void powerOff() {
state.off();
}
}
抽象状态类:
public interface State {
/**
* 状态对应的处理
*/
public void connect();
public void off();
}
具体状态类:
//关闭状态,触发没有任何操作
public class ConcreteStateA implements State {
@Override
public void connect() {
}
@Override
public void off() {
}
}
//开启状态
public class ConcreteStateB implements State {
@Override
public void connect() {
System.out.println("连接成功");
}
@Override
public void off() {
System.out.println("断开成功");
}
}
客户端类:
public class Client {
public static void main(String[] args) {
//创建状态
State state=new ConcreteStateOpen();
//创建环境
Context context=new Context();
//将状态设置到环境中
context.setState(state);
//具体请求
context.powerOn();
context.powerOff();
}
}
如果你觉得每次要重新手动创建一个状态麻烦,我们可以改一下环境类:
public class Context {
//维护一个State子类的实例,这个实例定义了当前的状态
private State state;
public void setState(State state) {
this.state = state;
}
/**
* 用户感兴趣的接口方法
*/
public void powerOn(){
setState(new ConcreteStateOpen());
System.out.println("开启啦");
}
public void powerOff() {
setState(new ConcreteStateClose());
System.out.println("关闭啦");
}
public void C() {
state.connect();
}
public void O() {
state.off();
}
}
这样在客户端类里面更改状态更加方便了:
public class Client {
public static void main(String[] args) {
Context context=new Context();
//设置开启状态
context.powerOn();
//开启
context.C();
//关闭
context.O();
//设置关闭状态
context.powerOff();
context.C();
}
}
优点
- 封装转换过程,也就是转换规则
- 枚举可能的状态,因此,需要事先确定状态种类。
- 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
- 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
- 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点
状态模式的使用必然会增加系统类和对象的个数
总结
状态模式的关键之处在于不同的状态下对于同一个行为有不同的响应,其实就是使用多态实现的一个具体的if-else语句。但是减少了代码的逻辑耦合。在Android中,状态模式最常用的案例就是用户登陆系统