GeekTop
  • 首页
  • 关于

GeekTop

不止代码

有限状态机和状态模式

有限状态机和状态模式

2020年11月18日 Alex Comments 0 Comment

有限状态机(Finite-State Machine)是一种计算模型,状态模式是一种设计模式,两者不可同日而语。但是,有限状态机可以通过状态模式来实现。

所谓的有限,指的是状态个数是有限的,每个状态可以迁移到零个到多个状态,输入的时间决定了状态往哪个方向迁移。

有限状态机的特征是离散、有限。但是,世界上绝大多数事物,没有办法使用状态机来表示,这些事物的状态比较复杂,可能有无限多个。比如,经济增长的变化,温度的变化。

当前状态/条件 状态A 状态B
条件X … …
条件Y 状态B …

状态机可以归纳为:现态、事件、动作、次态。

  • 现态:指的是对象当前所处的状态
  • 事件:发生一个事件,可能执行状态迁移
  • 动作:发生一个事件后执行的操作。事件发生会触发相应的动作。此时可能发生状态的迁移,也可能不发生。
  • 次态:“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。

状态模式

状态模式,可以作为实现状态机的一种方式:

在软件开发过程中,对象需要根据不同的情况做出不同的行为,影响对象行为的一个或者多个属性我们把它称为状态。当有外部事件影响对象的状态发生改变时,对象的行为也会发生改变。状态模式可以在一定程度上优化密集的 if-else或者switch-case代码,类似条件判断语句会过于臃肿,可读性差,且不具备扩展性,维护难度也大。

状态模式的核心要点是把复杂的逻辑判断提取出来,用不同的类来表示,系统处于哪种情况,就使用相应的状态类来进行处理,这样做就能简化逻辑的判断。

但是状态模式也有缺点,最大的缺点就是会增加系统中类的数量,以后新增状态也要新增类,也有一定的复杂度。

从上图可以看出,状态模式主要有:

  • Context 类:环境上下文,维护一个当前状态
  • State 类:抽象类,定义对象的状态和行为
  • ConcreteState 类:实现抽象对象所定义的行为

实现FSM

实现一个FSM包含了几个要素:状态的管理、状态的监控、状态的触发、状态触发后引发的动作。

状态模式实现
//抽象状态类
abstract class State {
    public abstract void Handle(Context context);
}
//具体状态A类
class ConcreteStateA extends State {
    public void Handle(Context context) {
        System.out.println("当前状态是 A.");
        context.setState(new ConcreteStateB());
    }
}
//具体状态B类
class ConcreteStateB extends State {
    public void Handle(Context context) {
        System.out.println("当前状态是 B.");
        context.setState(new ConcreteStateA());
    }
}

//环境类
class Context {
    private State state;
    //定义环境类的初始状态
    public Context() {
        this.state = new ConcreteStateA();
    }
    //设置新状态
    public void setState(State state) {
        this.state = state;
    }
    //读取状态
    public State getState() {
        return (state);
    }
    //对请求做处理
    public void Handle() {
        state.Handle(this);
    }
}
枚举实现
public interface IPositionFSM {

    default IPositionFSM processFoo() {
        return this;
    }

    default IPositionFSM processBar() {
        return this;
    }
}

public enum PositionFSM implements IPositionFSM {
    State1 {
        @Override
        public IPositionFSM processFoo() {
            return State2;
        }
    },
    State2 {
        @Override
        public IPositionFSM processBar() {
            return State1;
        }
    };
}

总结

状态模式实现FSM略显复杂,一般情况下推荐使用枚举的方式。


参考资料:

  • 有限状态机

  • 确定有限状态自动机

  • 非确定有限状态自动机

  • TCP Operational Overview and the TCP Finite State Machine (FSM)

  • How to implement a FSM – Finite State Machine in Java

  • Java enum-based state machine (FSM): Passing in events

  • Akka Java FSM by Example

  • Java Finite State Machine Framework


编程
Java, 编程

Post navigation

NEXT
基于统计的图像目标检索
PREVIOUS
API安全设计

发表回复 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

最近文章

  • 姥姥
  • 设计一个可扩展的用户模型
  • 使用 Apple 的 Keychain 保存 SSH 的 passphase
  • 解决 ABA 问题
  • 关于 macOS 上面部分 emoji 无法显示的问题
  • 这些年我技术栈的变化
  • 搬瓦工、狗云、hostodo、oracle对比测试
  • Google Drive 无法上传文件
  • 使用 socks5 代理 git ssh 协议
  • 到底要不要“润”
  • 可复用的代码
  • 关于疫情的一点点反思
  • 我的风控策略(投资篇)
  • 我的风控策略(生活篇)
  • Spring Boot是如何处理异常的
  • 编码与解码
  • 基于统计的图像目标检索
  • 有限状态机和状态模式
  • API安全设计
  • 用户密码的存储策略

近期评论

  • ǝɔɐǝԀʎzɐɹϽ发表在《可复用的代码》
  • Alex发表在《可复用的代码》
  • ǝɔɐǝԀʎzɐɹϽ发表在《到底要不要“润”》
  • ǝɔɐǝԀʎzɐɹϽ发表在《可复用的代码》
  • ǝɔɐǝԀʎzɐɹϽ发表在《我的风控策略(生活篇)》
  • ǝɔɐǝԀʎzɐɹϽ发表在《如何写出简洁优雅的代码》
  • 张志亮发表在《如何写出简洁优雅的代码》

分类

  • AI (2)
  • Java应用安全之道 (1)
    • 加密与解密 (1)
  • Odoo (2)
  • Python (1)
  • 图像处理 (1)
  • 年鉴 (1)
  • 数据库 (10)
  • 编程 (14)
    • Spring (1)
  • 读书笔记 (2)
  • 运维 (5)
  • 随笔 (10)

归档

  • 2023年1月 (2)
  • 2022年8月 (1)
  • 2022年7月 (4)
  • 2022年6月 (2)
  • 2022年5月 (2)
  • 2022年4月 (3)
  • 2021年10月 (1)
  • 2021年7月 (1)
  • 2021年5月 (1)
  • 2020年11月 (1)
  • 2020年7月 (1)
  • 2020年3月 (2)
  • 2020年2月 (1)
  • 2019年1月 (1)
  • 2018年12月 (2)
  • 2018年11月 (2)
  • 2017年4月 (1)
  • 2016年11月 (1)
  • 2016年9月 (1)
  • 2016年7月 (1)
  • 2016年5月 (3)
  • 2016年4月 (2)
  • 2016年3月 (1)
  • 2016年2月 (2)
  • 2015年12月 (1)
  • 2015年11月 (2)
  • 2015年8月 (1)
  • 2015年4月 (1)
  • 2015年3月 (1)

标签

Database devops Java MySQL PostgreSQL Python shell Spring SpringBoot Spring Security 安全 年鉴 总结 编程 随笔
© 2015-2023   Geektop.net All Rights Reserved.