文章目录
前言
回忆下生活中状态流转的例子
从业多年的java 开发,对设计模式的认识还知之甚少,偶然下看过几个设计模式,单例,代理,构建者,工厂,策略,观察者,装饰器,今天我们来聊一聊状态模式;
一、什么是状态模式
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类
上述的讲法较为难以理解,通俗的讲,将对象的状态和对象本身做分离,使我们的代码设计职责更加单一,低耦合,且易于扩展;
二、实际场景

现有个小需求,需要实现自动挡汽车挂挡的功能;话不多说开始撸代码,代码如下:
java
package org.example.design.pattern.state;
// 档位类
public class Shift {
private State state = State.P;
// 往上推
public void turnUp() {
switch (state) {
case D:
System.out.println("OK..切N档");
state = State.N;
break;
case N:
state = State.R;
System.out.println("OK..切R档");
break;
case R:
state = State.P;
System.out.println("OK..切P档");
break;
case P:
System.out.println("WARN.. 推不动了");
break;
}
}
// 往下推
public void turnDown() {
switch (state) {
case D:
System.out.println("WARN.. 拉不动了");
break;
case N:
state = State.D;
System.out.println("OK..切D档");
break;
case R:
state = State.N;
System.out.println("OK..切N档");
break;
case P:
state = State.R;
System.out.println("OK.. 切R档");
break;
}
}
enum State {
D,
R,
N,
P
}
}
API 使用端代码
java
public static void main(String[] args) {
Shift shift = new Shift();
// 向上挂挡
shift.turnUp();
// 向下拉档
shift.turnDown();
}
代码简洁,三下五除二搞定;但是思考,现有的自动挡车辆设计只有这么几个档位,后续如果又增加档位呢? 低速挡,高速挡? 这样岂不档位代码的2 个方法都要修改?(代码的开闭原则也没有了)另外现在还只是 生活中这种简单的挂挡逻辑,若是业务系统中的复杂业务,这么多switch case,也头疼;
思考: 代码能怎么优化呢
1.优化
先剥离出这段switch case 判断逻辑
java
// 状态接口,向上推档方法,和向下拉退档方法
public interface State {
/**
* 向上推档
*
* @param shift
*/
void turnUp(Shift shift);
/**
* 向下拉档
*
* @param shift
*/
void turnDown(Shift shift);
}
每个档位各自的推档退档逻辑,这样就将对象的状态和对象逻辑分离
java
import org.example.design.pattern.state.Shift;
import org.example.design.pattern.state.State;
// P档
public class P implements State {
@Override
public void turnUp(Shift shift) {
System.out.println("WARN!! 已是P 档无法向上推");
}
@Override
public void turnDown(Shift shift) {
shift.setState(this);
}
}
// N档
public class N implements State {
@Override
public void turnUp(Shift shift) {
shift.setState(new R());
}
@Override
public void turnDown(Shift shift) {
shift.setState(new D());
}
}
// D档
public class D implements State {
@Override
public void turnUp(Shift shift) {
shift.setState(new N());
}
@Override
public void turnDown(Shift shift) {
System.out.println("WARN!! 已是D 档无法向下拉");
}
}
// R档
public class R implements State {
@Override
public void turnUp(Shift shift) {
shift.setState(new P());
}
@Override
public void turnDown(Shift shift) {
shift.setState(new N());
}
}
2. 思考
我们的档位类(shift)代码该如何设计呢?又如何去掉 那些switch case 代码呢?
java
package org.example.design.pattern.state;
import org.example.design.pattern.state.dw.P;
public class Shift {
// 默认是P挡
private State state = new P();
public void turnUp() {
state.turnUp(this);
}
public void turnDown() {
state.turnDown(this);
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
档位类里边的状态和对应状态的逻辑已经分离,后续需要添加档位或者整理,只需实现 State 接口新增修改即可;
总结
相当实用的设计模式,有机会定要引入代码中;