首页 > 其他分享 >初识设计模式 - 状态模式

初识设计模式 - 状态模式

时间:2022-10-25 08:58:07浏览次数:80  
标签:状态 代码 模式 状态机 State 初识 设计模式 public 马里奥

简介

状态模式(State Design Pattern)的定义是,允许一个对象在内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

在状态模式中,通常有两种方式实现状态转换:统一由环境类来负责状态之间的转换;由具体状态类来负责状态之间的转换。

状态机

概念

状态模式一般用于实现状态机,而状态机常用在游戏、工作流引擎等系统开发中。状态机的实现方式有多种,除了状态模式,比较常用的还有分支逻辑法和查表法。

状态机会有 3 个组成部分:状态(State)、事件(Event)、动作(Action)。

拿“超级马里奥”游戏来举例,其中马里奥形态的转变就是一个状态机:初始状态是小马里奥,吃蘑菇这个事件会触发状态的转移,从小马里奥转变成超级马里奥,以及触发动作的执行(增加积分)。

分支逻辑法

最简单的状态机实现方式就是分支逻辑法,其理解非常简单,就是将每一个状态转移都直译成代码。

其缺点是,代码中会充斥着 if-else 或 switch 分支判断逻辑,甚至是嵌套的分支判断逻辑,当状态较多时,代码的可读性会比较低。

查表法

查表法的实现逻辑是,将状态、事件和动作三者存储到一个二维表中,这样可以清晰地表示,一个动作发生某个事件时,会转移到怎样的状态以及触发怎样的动作。

状态机查表法二维表

在实现过程中,将二维表的数据存储到配置文件中,可以通过动态地修改配置文件以达到修改状态机的目的。

具体实现

仍然还是拿“超级马里奥”游戏来举例说明,初始状态是小马里奥,吃蘑菇这个事件会触发状态的转移,从小马里奥转变成超级马里奥,以及触发动作的执行(增加积分)。

首先,定义一个抽象状态 State 接口,其代码示例如下:

public interface State {
    // 声明抽象业务方法,不同的具体状态可以有不同的方法实现
    void handle();
}

对于小马里奥状态,定义一个实现 State 接口的 SmallState 类,其代码示例如下:

public class SmallState implements State {
    @Override
    public void handle() {
        // 业务方法的具体实现
        System.out.println("变成小马里奥状态");
    }
}

对于超级马里奥状态,定义一个实现 State 接口的 SuperState 类,其代码示例如下:

public class LargeState implements State {
    @Override
    public void handle() {
        // 业务方法的具体实现
        System.out.println("变成超级马里奥状态");
    }
}

在状态模式中,需要创建一个 Context 类用于保存对于一个具体状态对象的引用,并且负责状态的保持和转变。其代码示例如下:

public class Context {
    private State state;

    public void setState(State state) {
        // 注入状态对象
        this.state = state;
    }

    public void request() {
        // 调用状态对象的业务方法
        this.state.handle();
    }
}

对于客户端,直接操作 Context 对象并根据状态的转变传入不同的状态对象,这样即可实现状态机的功能,其代码示例如下:

class StateDemo {
    public static void main(String[] args) {
        Context context = new Context();

        State smallState = new SmallState();
        context.setState(smallState);
        // 变成小马里奥状态
        context.request();

        State largeState = new LargeState();
        context.setState(largeState);
        // 变成超级马里奥状态
        context.request();
    }
}

总结

优点

状态模式的主要优点如下:

  • 状态模式统一封装了状态的转换规则,对状态转换代码进行集中管理
  • 将不同的状态引入独立的对象中使得状态转换变得更加明确,且减少对象间的相互依赖
  • 状态的职责分明,通过定义新的子类可以很容易地增加新的状态和转换

缺点

状态模式的主要缺点如下:

  • 每个状态都会新增一个具体的状态子类,导致系统的运行开销增大
  • 状态模式的结构和实现都较为复杂,使用不当会导致程序结构和代码的混乱
  • 对于可以切换的状态模式,增加新的状态类需要修改那些负责状态转换的源码,否则无法切换到新增的状态,而且修改某个状态类的行为也要修改对应类的源码

适用场景

状态模式的适用场景如下:

  • 对象的行为依赖于它的状态,状态的改变将导致行为的变化
  • 在代码中包括大量与对象状态有关的条件语句

标签:状态,代码,模式,状态机,State,初识,设计模式,public,马里奥
From: https://www.cnblogs.com/fatedeity/p/16823734.html

相关文章

  • C++ 不知树系列之初识树(树的邻接矩阵、双亲孩子表示法……)
    1.前言树是一种很重要的数据结构,最初对数据结构的定义就是指对树和图的研究,后来才广义化了数据结构这个概念。从而可看出树和图在数结构这一研究领域的重要性。树和图重......
  • Struts2-3概述与MVC模式深度剖析
    Struts深入浅出​​​Struts框架的优势​​​MVC的概念​MVC结构图MVC处理过程​MVC的优点​MVC的适用范围​JSP是一个独立的、自主完成所有任务......
  • Struts2-3概述与MVC模式深度剖析
    Struts深入浅出​​​Struts框架的优势​​​MVC的概念​MVC结构图MVC处理过程​MVC的优点​MVC的适用范围​JSP是一个独立的、自主完成所有任务......
  • javascript编程单线程之同步模式
    javascript编程单线程之同步模式主流的js环境都是单线程吗模式执行js代码,js采用为单线程的原因与最开始设计初衷有关,最早是运行在浏览器端的脚本语言,目的是为了实现页......
  • 代理模式
    packageJiekou;/***@authorliu$*@version1.0*@description:TODO*@date$$*///被代理类对象不调方法,把对象放到代理类里面调方法publicclassdaili{pub......
  • 【JS设计模式笔记】给我一张名片-工厂方法模式(创建型)
    广告展现例如,关于计算机培训广告资源需要投放,一批是Java的用绿色字体,一批是PHP的,用黄色字体,红色背景。//创建Java学科类varJava=function(content){ //将内容保......
  • 枚举、单例模式
    一、枚举Enum1.1简介1.概念:枚举就是表示一些固定的值(常量)使用枚举项表示这些固定的值每一个枚举项都是一个对象2.定义枚举类的语法:访问修饰符enum枚举类的......
  • 基于工厂模式和策略模式改造支付系统
    1.vo@Data@AllArgsConstructor@NoArgsConstructor@BuilderpublicclassPayVO{/***支付类型:egsendwyre*/privateStringpayType;/***端......
  • 设计模式总览
    设计模式是什么?在软件工程中,设计模式(DesignPattern)是对软件设计中常见问题的典型解决方案。它们就像能根据需求进行调整的预制蓝图,可用于解决代码中反复出现的设计问题。......
  • JavaScript 设计模式之策略模式
    什么是设计模式?为什么需要学习设计模式?学习设计模式的目的是:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编写真正工程化;设计模式是软件工......