闲话状态模式

文章目录


前言

回忆下生活中状态流转的例子

从业多年的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 接口新增修改即可;


总结

相当实用的设计模式,有机会定要引入代码中;

相关推荐
ok!ko2 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
2402_857589362 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰3 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
哎呦没4 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
编程、小哥哥4 小时前
netty之Netty与SpringBoot整合
java·spring boot·spring
IT学长编程5 小时前
计算机毕业设计 玩具租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·玩具租赁系统
莹雨潇潇5 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
杨哥带你写代码5 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
郭二哈6 小时前
C++——模板进阶、继承
java·服务器·c++