热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

初识设计模式–状态模式

简介状态模式(StateDesignPattern)的定义是,允许一个对象在内部状态改变时改变它的行为,对象看起来似乎修改了它的类。在状态模式中,通常有两种方式实现状态转换:统一由

简介

状态模式(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();
}
}

总结


优点

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



  • 状态模式统一封装了状态的转换规则,对状态转换代码进行集中管理

  • 将不同的状态引入独立的对象中使得状态转换变得更加明确,且减少对象间的相互依赖

  • 状态的职责分明,通过定义新的子类可以很容易地增加新的状态和转换


缺点

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



  • 每个状态都会新增一个具体的状态子类,导致系统的运行开销增大

  • 状态模式的结构和实现都较为复杂,使用不当会导致程序结构和代码的混乱

  • 对于可以切换的状态模式,增加新的状态类需要修改那些负责状态转换的源码,否则无法切换到新增的状态,而且修改某个状态类的行为也要修改对应类的源码


适用场景

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



  • 对象的行为依赖于它的状态,状态的改变将导致行为的变化

  • 在代码中包括大量与对象状态有关的条件语句

首发于翔仔的个人博客,点击查看更多。



推荐阅读
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • 深入理解 .NET 中的中间件
    中间件是插入到应用程序请求处理管道中的组件,用于处理传入的HTTP请求和响应。它在ASP.NET Core中扮演着至关重要的角色,能够灵活地扩展和自定义应用程序的行为。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文介绍了如何使用 Spring Boot DevTools 实现应用程序在开发过程中自动重启。这一特性显著提高了开发效率,特别是在集成开发环境(IDE)中工作时,能够提供快速的反馈循环。默认情况下,DevTools 会监控类路径上的文件变化,并根据需要触发应用重启。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 深入理解Tornado模板系统
    本文详细介绍了Tornado框架中模板系统的使用方法。Tornado自带的轻量级、高效且灵活的模板语言位于tornado.template模块,支持嵌入Python代码片段,帮助开发者快速构建动态网页。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 本文介绍如何在Spring Boot项目中集成Redis,并通过具体案例展示其配置和使用方法。包括添加依赖、配置连接信息、自定义序列化方式以及实现仓储接口。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
author-avatar
嗷唔喵_105
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有