[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式

news2024/11/16 21:59:46

前言:
为什么之前写过Golang 版的设计模式,还在重新写Java 版?
答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。
为什么类图要附上uml
因为很多人学习有做笔记的习惯,如果单纯的只是放一张图片,那么学习者也只能复制一张图片,可复用性较低,附上uml,方便有新理解时,快速出新图。


🔥[设计模式Java实现附plantuml源码]专链

  • 创建型
  1. 确保对象的唯一性~单例模式
  2. 集中式工厂的实现~简单工厂模式
  3. 多态工厂的实现——工厂方法模式
  4. 产品族的创建——抽象工厂模式
  5. 对象的克隆~原型模式
  6. 复杂对象的组装与创建——建造者模式
  • 结构型
  1. 提供统一入口——外观模式
  2. 扩展系统功能——装饰模式
  3. 树形结构的处理——组合模式
  4. 对象的间接访问——代理模式
  5. 不兼容结构的协调——适配器模式
  6. 处理多维度变化——桥接模式
  7. 实现对象的复用——享元模式
  • 行为型
  1. 请求的链式处理——职责链模式

  2. 请求发送者与接收者解耦——命令模式

  3. 遍历聚合对象中的元素——迭代器模式

  4. 协调多个对象之间的交互——中介者模式

  5. 对象间的联动~观察者模式

  6. 撤销功能的实现——备忘录模式


状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化。对于客户端而言,无须关心对象状态的转换以及对象所处的当前状态,无论对于何种状态的对象,客户端都可以一致性地处理。
:::info
状态模式定义如下:状态模式(State Pattern):
允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行为型模式。
:::
在状态模式中引入了抽象状态类和具体状态类,它们是状态模式的核心,其结构如图所示。
在这里插入图片描述

@startuml

class Context {
- state
+ setState(State state)
+ request()
}

note left of Context::request
state.handler()
end note


abstract class State {
+ handler()
} 

class ConcreteStateA extends State {
+ handler()
}

class ConcreteStateB extends State {
+ handler()
}

Context *-right-> State: state

@enduml

(1)Context(环境类):环境类又称为上下文类,它是拥有多种状态的对象。由于环境类的状态存在多样性且在不同状态下对象的行为有所不同,因此将状态独立出去形成单独的状态类。在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象。
(2)State(抽象状态类):它用于定义一个接口以封装与环境类的一个特定状态相关的行为。在抽象状态类中声明各种不同状态对应的方法,而在其子类中实现这些方法。由于不同状态下对象的行为可能不同,因此在不同子类中方法的实现可能存在不同,相同的方法可以写在抽象状态类中。
(3)ConcreteState(具体状态类):它是抽象状态类的子类,每个子类实现一个与环境类的一个状态相关的行为。每个具体状态类对应环境类的一个具体状态,不同的具体状态类其行为有所不同。

:::info
在状态模式的使用过程中,一个对象的状态之间还可以进行相互转换。通常有以下两种实现状态转换的方式:
:::
(1)统一由环境类来负责状态之间的转换。此时,环境类还充当了状态管理器(State Manager)角色。在环境类的业务方法中通过对某些属性值的判断实现状态转换,还可以提供一个专门的方法用于实现属性判断和状态转换。

...
public void changeState() {
	if(value==0) {
        this.setState(new ConcreteStateA());
    }else if(){
        
    } 
    ...
    else{
        
    }
}
...

(2)由具体状态类来负责状态之间的转换。可以在具体状态类的业务方法中判断环境类的某些属性值再根据情况为环境类设置新的状态对象,实现状态转换。同样,也可以提供一个专门的方法来负责属性值的判断和状态转换。此时,状态类与环境类之间将存在依赖或关联关系,因为状态类需要访问环境类中的属性值。代码片段如下:

...
public void changeState(Context ctx) {
    if(ctx.getValue() == 1) {
        ctx.setState(new ConcreteStateA());
    } else if {
        ...
    }else {
        ...
    }
}
...

简单实现

package behavior;

public class StateDemo {
    public static void main(String[] args) {

        Context context = new Context();
        State stateA = new ConcreteStateA();
        context.setState(stateA);
        context.request();
        State stateB = new ConcreteStateB();
        context.setState(stateB);
        context.request();

    }

    public static abstract class State {
        abstract public void handler();
    }

    public static class ConcreteStateA extends State {
        @Override
        public void handler() {
            System.out.println(">>>>>> A");
        }
    }

    public static class ConcreteStateB extends State {
        @Override
        public void handler() {
            System.out.println(">>>>>> B");
        }
    }

    public static class Context {
        private State state;

        public void setState(State state) {
            this.state = state;
        }

        public void request() {

            state.handler();
        }

    }

}

总结

状态模式将一个对象在不同状态下的不同行为封装在一个个状态类中。通过设置不同的状态对象可以让环境对象拥有不同的行为,而状态转换的细节对于客户端而言是透明的,方便了客户端的使用。在实际开发中,状态模式具有较高的使用频率,在工作流、游戏等软件中状态模式都得到了广泛应用,例如公文状态的转换、游戏中角色的升级等。

主要优点

状态模式的主要优点如下:
(1)封装了状态的转换规则。在状态模式中可以将状态的转换代码封装在环境类或者具体状态类中,对状态转换代码进行集中管理,而不是分散在一个个业务方法中。
(2)将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境对象拥有不同的行为。
(3)允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块。状态模式可以避免使用庞大的条件语句来将业务方法和状态转换代码交织在一起。
(4)可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

主要缺点

状态模式的主要缺点如下:
(1)状态模式的使用必然会增加系统中类和对象的个数,导致系统运行开销增大。
(2)状态模式的程序结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,增加系统设计的难度。
(3)状态模式对开闭原则的支持并不太好。增加新的状态类需要修改那些负责状态转换的源代码,否则无法转换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。

适用场景


🚀 作者简介:作为某云服务提供商的后端开发人员,我将在这里与大家简要分享一些实用的开发小技巧。在我的职业生涯中积累了丰富的经验,希望能通过这个博客与大家交流、学习和成长。技术栈:Java、Golang、PHP、Python、Vue、React


本文收录于三木的
💐 「设计模式」专栏
此外三木还有以下专栏在同步更新~

🌼 「AI」专栏

🔥「面试」这个专栏的灵感来自于许多粉丝私信,大家向我咨询有关面试的问题和建议。我深感荣幸和责任,希望通过这个专栏,能够为大家提供更多关于面试的知识、技巧和经验。我们将一起探讨面试。期待粉丝们ssp的offer喜讯。

🎈 「Java探索者之路」系列专栏,这个专栏旨在引领Java开发者踏上一段真正探索Java世界的旅程。
我们将深入探讨Java编程的方方面面,从基础知识到高级技巧,从实践案例到最新趋势,帮助你成为一名卓越的Java探索者。如果有想进入Java后端领域工作的同学,这个专栏会对你有所帮助,欢迎关注起来呀

🌊 「Python爬虫」的入门学习系列,大家有兴趣的可以看一看


🌹一起学习,互三互访,顺评论区有访必回,有关必回!!!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1476676.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2 + axios + mock.js封装过程,包含mock.js获取数据时报404状态的解决记录,带图文,超详细!!!

vue axios mock.js 以下是封装的过程,记录一下 1、首先先了解什么是mock.js的用途及特点 官网地址:Mock.js (mockjs.com) 作用:生成随机数据,拦截 Ajax 请求 优势: 2、了解axios的原理及使用 官网地址&#xff1a…

Python把excel内容保存为图片(非统计图而是纯原表格数据)

一、引入 excel2img 库,没有的话使用 pip install excel2img进行安装 二、采用如下方法进行图片生成 excel文件名为:111.xlsx excel表格里面的sheet名称列表为 [Sheet1, Sheet2] 最终保存为以sheet名称.png的图片 支持跨表格合并项 import excel2i…

【大数据】Flink SQL 语法篇(八):集合、Order By、Limit、TopN

Flink SQL 语法篇(八):集合、Order By、Limit、TopN 1.集合操作2.Order By、Limit 子句2.1 Order By 子句2.2 Limit 子句 3.TopN 子句 1.集合操作 集合操作支持 Batch / Streaming 任务。 UNION:将集合合并并且去重。UNION ALL&a…

MySql-多表设计-一对多-外键

目录 外键约束问题分析问题解决 实例通过SQL语句操作物理外键和逻辑外键 外键约束 表结构创建完毕后,我们看到两张表的数据分别为: 现在员工表中有9个员工都归属于2号部门,当删除了号部门后,数据变为: 2号部门被删除…

什么是电子邮件客户端?如何选择合适的邮箱客户端?

“从1到10分,你会如何评价我们的电子邮件服务?” 无论你的评分是多少,影响你评分的一个重要因素肯定是电子邮件客户端提供的功能。 电子邮件客户端应该具有基本而漂亮的高级功能,以使迁移过程更容易。此外,应该有一些…

leetcode — 动态规划 — 打家劫舍、完全平方数

1 打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房…

Vue官网“食用指南”

把Vue官网当做一个工具来用,有问题,先来官网查一查。 官网中常用的板块 官网:https://cn.vuejs.org/上手后,最常用的模块是【快速上手】【API】。所以务必要知道这两个模块在哪里,怎么使用。![image.png](https://img…

VPX基于全国产飞腾FT-2000+/64核+复旦微FPGA的计算刀片

6U VPX计算板 产品简介 产品特点 飞腾计算平台,国产化率100% VPX-MPU6902是一款基于飞腾FT-2000/64核的计算刀片,主频2.2GHz,负责业务数据流的管控和调度。搭配自带独立显示芯片的飞腾X100芯片,可用于于各类终端及服务器类应用场…

R语言使用dietaryindex包计算NHANES数据多种健康饮食指数 (HEI等)(1)

健康饮食指数 (HEI) 是评估一组食物是否符合美国人膳食指南 (DGA) 的指标。Dietindex包提供用户友好的简化方法,将饮食摄入数据标准化为基于指数的饮食模式,从而能够评估流行病学和临床研究中对这些模式的遵守情况,从而促进精准营养。 该软件…

能在手机上运行,仅仅0.5B大小的小语言模型MobiLlama

模型介绍 该模型基于LLaMA-7B架构设计,旨在能够在边缘设备上高效运行,无需将数据发送到远程服务器或云端处理。如智能手机、平板电脑、智能手表等。MobiLlama模型虽然体积小、对资源的需求低,但仍能提供高精度的语言理解和生成能力。项目还提…

fastjson序列化MessageExt对象问题(1.2.78之前版本)

前言 无论是kafka&#xff0c;还是RocketMq&#xff0c;消费者方法参数中的MessageExt对象不能被 fastjson默认的方式序列化。 一、查看代码 Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,ConsumeConcurrentlyContext context) {t…

C语言——深度剖析数据在内存中的存储——第2篇——(第25篇)

坚持就是胜利 文章目录 三、浮点型在内存中的存储1、一个例子2、浮点数存储规则1、IEEE 754对 有效数字M 和 指数E &#xff0c;还有一些特别规定。2、至于 指数E&#xff0c;情况比较复杂&#xff0c;首先&#xff0c;E 为 一个无符号整数(unsigned int)3、然而&#xff0c;指…

防御保护:防火墙内容安全

一、IAE&#xff08;Intelligent Awareness Engine&#xff09;引擎 二、深度检测技术(DFI和DPI&#xff09; 1.DPI – 深度包检测技术 DPI主要针对完整的数据包&#xff08;数据包分片&#xff0c;分段需要重组&#xff09;&#xff0c;之后对数据包的内容进行识别。&#x…

c# .net8 香橙派orangepi + hc-04蓝牙 实例

这些使用c# .net8开发&#xff0c;硬件 香橙派 orangepi 3lts和 hc-04蓝牙 使用场景&#xff1a;可以通过这个功能&#xff0c;手机连接orangepi进行wifi等参数配置 硬件&#xff1a; 1、带USB口的linux开发板orangepi 2、USB 转TTL 中转接蓝牙&#xff08;HC-04) 某宝上买…

openGauss学习笔记-230 openGauss性能调优-系统调优-配置并行查询功能

文章目录 openGauss学习笔记-230 openGauss性能调优-系统调优-配置并行查询功能230.1 适用场景与限制230.2 资源对SMP性能的影响230.3 其他因素对SMP性能的影响230.4 配置步骤 openGauss学习笔记-230 openGauss性能调优-系统调优-配置并行查询功能 openGauss的SMP并行技术是一…

双流机场到天府机场ADS-B数据导入MATLAB

MATLAB导入数据 导入的数据Excel部分截图&#xff1a; 一些处理 % 导入外部轨迹数据并转成标准形式 clear;clc; %% 导入&预处理 [NUM,TXT,RAW]xlsread(2021年10月31日CTU-TFU); time_cell RAW(3:end,1); %拉取时间数据&#xff08;cell&#xff09; time_char char(t…

【清理mysql数据库服务器二进制日志文件】

清理前后比对 清理前占用 86% &#xff1a; 清理后占用 29% &#xff1a; 排查占用磁盘较大的文件 检测磁盘空间占用 TOP 10 # 检测磁盘空间占用 TOP 10 $ sudo du -S /var/log/ | > sort -rn | # -n选项允许按数字排序。-r选项会先列出最大数字&#xff08;逆序&#x…

智慧应急:构建全方位、立体化的安全保障网络

一、引言 在信息化、智能化快速发展的今天&#xff0c;传统的应急管理模式已难以满足现代社会对安全保障的需求。智慧应急作为一种全新的安全管理模式&#xff0c;旨在通过集成物联网、大数据、云计算、人工智能等先进技术&#xff0c;实现对应急事件的快速响应、精准决策和高…

eltable 合计行添加tooltip

eltable 合计行添加tooltip 问题描述&#xff1a; eltable 合计行单元格内容过长会换行&#xff0c;需求要求合计行数据超长显示 … &#xff0c;鼠标 hover 时显示提示信息。 解决方案&#xff1a;eltable合计行没有对外的修改接口&#xff0c;想法是 自己实现一个tooltip&a…

代码随想录刷题笔记-Day25

1. 分割回文串 131. 分割回文串https://leetcode.cn/problems/palindrome-partitioning/ 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 1&#xf…