设计模式:状态模式

2023-09-17 16:24:51


状态模式(State Pattern)是一种行为型设计模式,用于解决对象在不同状态下的行为变化问题。状态模式允许对象在内部状态发生改变时改变其行为,使得对象的行为可以根据状态的改变而灵活变化。
在状态模式中,对象的行为会根据其内部状态的改变而变化,但对外部来说,对象的接口保持一致。状态模式通过将对象的状态抽象成不同的类,每个状态类都实现了相同的接口,从而使得状态的切换和行为的变化更加清晰和可控。

组件

状态模式通常包含以下组件:

  1. 环境(Context):定义了客户端所感兴趣的接口,维护一个当前状态对象的引用。
  2. 抽象状态(State):定义了一个接口,用于封装与环境的一个特定状态相关的行为。
  3. 具体状态(Concrete State):实现了抽象状态接口,具体实现了与特定状态相关的行为。

代码示例

class Context {
    private State state;
     public void setState(State state) {
        this.state = state;
    }
     public void request() {
        state.handle(this);
    }
}
 // 抽象状态类
interface State {
    void handle(Context context);
}
 // 具体状态类A
class ConcreteStateA implements State {
    public void handle(Context context) {
        System.out.println("当前状态是A");
        // 在状态A下的具体操作
        context.setState(new ConcreteStateB());
    }
}
 // 具体状态类B
class ConcreteStateB implements State {
    public void handle(Context context) {
        System.out.println("当前状态是B");
        // 在状态B下的具体操作
        context.setState(new ConcreteStateA());
    }
}
 // 客户端代码
public class Main {
    public static void main(String[] args) {
        Context context = new Context();
        context.setState(new ConcreteStateA());
         context.request();
        context.request();
    }
}

在上述示例中,我们定义了一个环境类(Context)和两个具体状态类(ConcreteStateA和ConcreteStateB),它们都实现了抽象状态类(State)的接口。在环境类中,我们维护了一个当前状态对象的引用,并提供了切换状态和执行请求的方法。具体状态类实现了在特定状态下的具体操作,并在操作完成后切换到另一个状态。

在客户端代码中,我们创建了一个环境对象,并初始设置为具体状态A。然后通过调用环境对象的请求方法,可以触发状态的切换和相应状态下的操作。

这个示例展示了如何使用Java实现状态模式,通过状态对象的切换来改变对象的行为。状态模式可以使得对象的行为随状态的改变而变化,提高代码的可维护性和可扩展性。

源码中使用

在源码中,状态模式有很多应用。以下是一些常见的源码中使用状态模式的情况:

  1. 订单状态管理:在电子商务系统中,订单通常具有多个状态,如待支付、已支付、已发货等。使用状态模式可以将每个状态封装成一个状态类,并在订单对象中管理和切换状态。
  2. 线程状态管理:在Java中,线程具有多个状态,如新建、运行、等待等。使用状态模式可以将每个状态封装成一个状态类,并通过状态转换来管理线程的状态。
  3. 游戏角色状态管理:在游戏开发中,游戏角色通常具有多个状态,如正常、受伤、死亡等。使用状态模式可以将每个状态封装成一个状态类,并在游戏角色对象中管理和切换状态。
  4. 交通信号灯控制:交通信号灯具有多个状态,如红灯、绿灯、黄灯等。使用状态模式可以将每个状态封装成一个状态类,并在信号灯对象中管理和切换状态。

优缺点

优点:

  1. 将状态相关的行为封装到不同的状态类中,使得状态转换更加明确和简化,提高代码的可读性和可维护性。
  2. 遵循开闭原则,当需要新增状态时,只需新增对应的状态类,而无需修改现有代码。
  3. 将状态转换逻辑集中管理,避免了大量的条件语句,提高了代码的可扩展性和灵活性。
  4. 状态模式可以让对象在不同状态下具备不同的行为,使得对象的行为更加动态和可定制。
    缺点:
  5. 状态模式会增加类的数量,每个状态都需要一个对应的状态类,如果状态较多,会导致类的数量增加,增加了系统的复杂性。
  6. 当状态转换较为复杂时,可能会导致状态类之间的交互复杂,增加了代码的理解和维护难度。
  7. 如果状态之间存在共享的数据,可能需要在各个状态类之间传递数据,增加了数据传递的开销和复杂性。

总结

状态模式通过将状态封装成独立的状态类,使得状态转换更加清晰和简化,提高了代码的可读性和可维护性。它遵循开闭原则,具有良好的扩展性和灵活性。然而,状态模式也会增加类的数量和复杂性,需要权衡使用。

更多推荐

Linux命令历史记录管理:使用history命令提高工作效率

文章目录引言1.1关于history命令1.2history命令的作用和用途基本用法2.1查看历史命令列表2.2执行历史命令2.3使用历史命令编号历史命令记录和保存3.1历史命令的存储位置3.2修改历史命令记录数量3.3清除历史命令记录搜索历史命令4.1使用关键字搜索4.2按日期和时间搜索4.3结合其他命令进行高级搜索

众佰诚:抖音开网店选品要怎么做

在移动互联网时代,抖音已经成为了一个风靡全球的社交媒体平台,吸引了数以亿计的用户。因此,许多人看到了在抖音上开设网店的商机,但要成功经营一家抖音网店,选品是至关重要的一环。下面将介绍一些关于如何在抖音上选择合适的商品的方法。确定目标受众:在开设抖音网店之前,首先要明确自己的目标受众是谁。了解你的受众的年龄、性别、兴趣爱

MLAgents (1) 球移动到指定立方体目标

1、ML-Agents库介绍ML-Agents库,训练用于2D、3D、VR/AR游戏的智能agent,经过训练的agent可用于多种目的,包括:控制NPC行为(采用各种设置,例如多个agent和对抗)、对游戏内部版本进行自动化测试、以及评估不同游戏设计决策的预发布版本2、Unity中创建立方体、球和地面球——玩家移动和

【iOS】ViewController的生命周期

文章目录前言一、UIViewController生命周期有关函数二、执行顺序注意点loadview:前言在iOS开发中UIViewController扮演者非常重要的角色,它是视图view和数据model的桥梁,通过UIViewController的管理有条不紊的将数据展示在视图上。作为UIKit中最基本的一个类,一般

数据可视化大屏模板 | 保姆级使用教程

近来很多朋友私信咨询怎么下载使用数据可视化大屏模板,在这里就给大家做一个相对简单的教程总结。有需要的朋友记得先收藏保存,以便不时之需。数据可视化大屏制作软件:奥威BI系统数据可视化报表模板板块:模板秀主要操作:点击、拖拉拽适用人群以及场景:所有具体操作步骤:1、登录奥威BI系统后,通过点击、拖曳的方式上传数据源(该过程

【深度学习】 Python 和 NumPy 系列教程(廿二):Matplotlib详解:2、3d绘图类型(8)3D饼图(3D Pie Chart)

一、前言Python是一种高级编程语言,由GuidovanRossum于1991年创建。它以简洁、易读的语法而闻名,并且具有强大的功能和广泛的应用领域。Python具有丰富的标准库和第三方库,可以用于开发各种类型的应用程序,包括Web开发、数据分析、人工智能、科学计算、自动化脚本等。Python本身是一种伟大的通用编程

虚拟人运营 | 金融品牌如何借助数字人IP撬动年轻圈层?

近年来,金融行业在不断尝试寻找一种新方式,去探索触及Z世代年轻圈层,数字人作为数字化时代的新介质,成为了金融业链接年轻人的新载体。在银行的应用场景里,主要打造智能客服、数字员工、虚拟主播等。如浦发银行数字员工“小浦”、百信银行数字员工“AIYA”、宁波银行智能客服“小宁”、平安银行虚拟主播“平安小财娘”等等...01数

蛤蟆先生去看心理医生笔记

自我状态儿童自我状态:行为和感受像个孩子。由童年残留的遗迹搭建而成,包含小时候体验的所有情感(儿童的基本情感)和随后演变的行为模式。行为和感受像个孩子。由童年残留的遗迹搭建而成,包含小时候体验的所有情感(儿童的基本情感)和随后演变的行为模式。简单点说,就是我们在长大后,依旧自动做出和小时候一样的反应,童年时的情感和行为

C语言关于自定义字符函数和字符串函数的相关笔试题(找工作必看)

本篇字符函数和字符串函数求字符串长度strlen长度不受限制的字符串函数strcpystrcatstrcmp长度受限制的字符串函数介绍strncpystrncatstrncmp字符串查找strstrstrtok错误信息报告strerror内存操作函数memcpymemmovememsetmemcmp在我们笔试时,很有可

C语言中的类型转换有哪些方式?

C语言中的类型转换是将一个数据类型的值转换为另一个数据类型的值的过程。类型转换在编程中非常常见,因为它允许您在不损失数据的情况下在不同数据类型之间进行操作和赋值。在C语言中,类型转换有多种方式,包括隐式类型转换和显式类型转换。本文将详细介绍这些类型转换方式以及它们的应用场景。隐式类型转换隐式类型转换,也称为自动类型转换

Centos7安装wps无法打开及字体缺失的问题解决

在centos7上安装了最新的wps2019版本的wps-office-11.1.0.11704-1.x86_64.rpm,生成了桌面图标并信任,可以新建文件,但是软件无法打开。在终端执行如下命令,用命令行启动wps:cd/opt/kingsoft/wps-office/office6/./wps提示"/lib64/l

热文推荐