设计模式(12)状态模式

参考【设计模式】用Java实现状态模式_java 状态模式_卷帘的博客-CSDN博客

一、介绍:

1、状态模式:是一种行为设计模式,它允许对象在内部状态发生改变时改变其行为。该模式将对象的行为包装在不同的状态类中,使得对象的行为可以根据其当前状态动态改变。

2、组成:状态模式的核心思想是通过将对象的行为包装在不同的状态类中,使得对象可以根据其当前状态来改变行为,而不需要使用大量的条件判断语句。通常由以下几个角色组成:

(1)环境类(Context):环境类是拥有状态的对象,它将会根据当前状态来执行相应的行为。它维护了一个对抽象状态类的引用,用于切换和委托不同的状态处理。

(2)抽象状态类(State):抽象状态类定义了一个接口,用于具体状态类的实现。在该接口中声明了具体状态类需要实现的方法。

(3)具体状态类(Concrete State):具体状态类实现了抽象状态类的接口,并负责定义该状态下的具体行为。它包含了对环境类的引用,可以根据需要切换环境类的状态。

3、UML类图:

4、适用场景:

(1)当一个对象的行为取决于其内部状态,并且需要在运行时根据状态改变行为时,状态模式非常有用。它允许对象在不同状态下执行不同的操作,而不需要使用复杂的条件判断语句。

(2)当对象具有大量的状态以及与每个状态相关的行为时,状态模式可以提供一种结构化的方式来管理和组织这些状态和行为。每个状态都可以表示为一个独立的状态类,使得代码更加清晰、可读性更高。

(3)当需要向对象的状态变化进行动态扩展时,状态模式提供了一种灵活的解决方案。通过添加新的状态类,并相应地调整环境类与状态类之间的关联,可以轻松地增加新的状态和行为。

(4)当多个对象需要共享同一组状态时,状态模式可以减少重复代码的编写。通过将状态封装在独立的状态类中,多个对象可以共享相同的状态实例,从而节省内存和代码维护成本。

二、demo:

1、电商订单状态流转:

(1)环境类:

// 环境类 - 订单
class Order {
    private OrderState state;
 
    public Order() {
        state = new NewState();
    }
 
    public void setState(OrderState state) {
        this.state = state;
    }
 
    public void process() {
        state.processOrder(this);
    }
}

(2)抽象状态类:

// 抽象状态类
interface OrderState {
    void processOrder(Order order);
}

(3)具体状态类:

// 具体状态类 - 新订单
class NewState implements OrderState {
    public void processOrder(Order order) {
        System.out.println("Processing new order");
        // 在新订单状态下的处理逻辑
        // ...
        order.setState(new ShippedState()); // 切换状态
    }
}
 
// 具体状态类 - 已发货订单
class ShippedState implements OrderState {
    public void processOrder(Order order) {
        System.out.println("Processing shipped order");
        // 在已发货订单状态下的处理逻辑
        // ...
        order.setState(new DeliveredState()); // 切换状态
    }
}
 
// 具体状态类 - 已交付订单
class DeliveredState implements OrderState {
    public void processOrder(Order order) {
        System.out.println("Processing delivered order");
        // 在已交付订单状态下的处理逻辑
        // ...
    }
}

(4)使用示例

public class Main {
    public static void main(String[] args) {
        Order order = new Order();

        order.process(); // 处理新订单
        order.process(); // 处理已发货订单
        order.process(); // 处理已交付订单
    }
}


 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ-死信交换机和死信队列

1. 简介 DLX: Dead-Letter-Exchange 死信交换器,死信邮箱 2.代码示例 Configuration public class RabbitConfig {final static String exchangeNormalName "exchange.dlx.normal";final static String queueNormalName "queue.dlx.normal"…

H5新Api | requestIdleCallback - requestAnimationFram

文章目录 浏览器渲染机制事件循环机制宏队列与微队列浏览器中事件循环流程 requestAnimationFrame(rAF)requestAnimationFrame API requestIdleCallbackrequestIdleCallback API任务拆分requestIdleCallback的使用场景 浏览器渲染机制 每一轮 Event Loop 都会伴随着渲染吗&…

Mac/Linux安装使用 opengauss数据库步骤

问题背景 一般部署opengauss数据库在虚拟机中,Mac使用虚拟机步骤较为繁琐,可以使用Docker部署opengauss数据库。Linux也可以使用此方式来部署opengauss数据库。 1. 在docker官网下载Docker桌面版,m系列芯片选Apple Chip。如果是Linux就下载…

vue数组中的变更方法和替换方法

变更方法: Vue 能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新。这些变更方法包括: push():在数组末尾添加一个或者多个元素,返回新的长度。 var arr [1, 2, 3, 4, 5]; // 定义一个数组 arr.push(6…

python sqlalchemy(ORM)- 02 表关系

文章目录 创建连接事务和DBAPIORM 操作表关系ORM表示 1v1ORM表示 1vm 创建连接 sqlalchemy应用必须创建一个engine,用于连接数据库; from sqlalchemy import create_engine # 创建engine, 懒连接,在ORM中由Session管理 engine create_engi…

第二证券:AIGC概念活跃,焦点科技、三维通信涨停,万兴科技大涨

AIGC概念24日盘中走势生动,到发稿,万兴科技、三态股份涨超10%,焦点科技、三维通讯、我国科传等涨停,中文在线涨超9%,果麦文明、新国都涨约7%。 消息面上,各大电商途径于10月18-24日先后发动“双11”大促或…

国产CAN总线收发芯片DP1042 兼容替换TJA1042

说明 1 简述 DP1042是一款应用于 CAN 协议控制器和物理总线之间的接口芯片,可应用于卡车、公交、小汽车、工业控制等领域,支持 5Mbps CAN FD 灵活数据速率,具有在总线与 CAN 协议控制器之间进行差分信号传输的能力,完全兼容“ISO…

C指针 --- 进阶

目录 1. 字符指针 1.1. 一般使用 1.2. 另一种使用 2. 指针数组 3. 数组指针 3.1. 数组指针 3.2. 数组名和&数组名 3.3. 数组指针的用处 1. 传递一个数组 2. 传递数组首元素的地址 3. 数组指针处理一维数组 4. 数组指针处理二维数组 4. 数组传参和指针传参 4.1…

全连接层是什么,有什么作用?

大家好啊,我是董董灿。 如果你是搞AI算法的同学,相信你在很多地方都见过全连接层。 无论是处理图片的卷积神经网络(CNN),还是处理文本的自然语言处理(NLP)网络,在网络的结尾做分类…

2023.10.26-SQL测试题

employee表: department表: job表: location表: 题目及答案: -- (1).查询工资大于一万的员工的姓名(first_name与last_name用“.”进行连接)和工资-- select CONCAT(first_name,.,last_name) as 姓名 ,salary -…

Vue(uniapp)父组件方法和子组件方法执行优先顺序

涉及到的知识点:watch监控:先看问题,父组件从后端通过$ajax获取数据,在将父组件将值传输给子组件,使用子组件使用created钩子函数获取数据,按自己的想法应该是父组件先获取后端数据,在传入给子组…

引入个性化标签的协同过滤推荐算法研究_邢瑜航

第3章 引入个性化标签的I-CF推荐算法 3.2.2 相似性度量方法 3.2.3 改进后的算法步骤与流程

Python:一个函数可以被多个装饰器装饰

理解: 规律: 一个函数可以被多个装饰器装饰. wrapper1 wrapper2 def target():print(我是目标)规则和规律 wrapper1 wrapper2 TARGET wrapper2 wrapper1def wrapper1(fn): # fn: wrapper2.innerdef inner(*args, **kwargs):print("这里是wrapper1 …

【RabbitMQ 实战】12 镜像队列

一、镜像队列的概念 RabbitMQ的镜像队列是将消息副本存储在一组节点上,以提高可用性和可靠性。镜像队列将队列中的消息复制到一个或多个其他节点上,并使这些节点上的队列保持同步。当一个节点失败时,其他节点上的队列不受影响,因…

【网络协议】聊聊TCP的三挥四握

上一篇我们说了网络其实是不稳定的,TCP和UDP其实是两个不同的对立者,所以TCP为了保证数据在网络中传输的可靠性,从丢包、乱序、重传、拥塞等场景有自己的一套打法。 TCP格式 源端口和目标端口是不可缺少的,用以区分到达发送给拿…

【每日一题】掷骰子等于目标和的方法数

文章目录 Tag题目来源题目解读解题思路方法一:动态规划 写在最后 Tag 【动态规划】【数组】 题目来源 1155. 掷骰子等于目标和的方法数 题目解读 你手里有 n 个一样的骰子,每个骰子都有 k 个面,分别标号 1 到 n。给定三个整数 n&#xff0…

java异常处理

异常处理分为三类: 检查性异常 用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。 运行时异常 运行时异常是可能被程序员避免的异常&#xf…

2023深耕kotlin,谈谈前景

为什么学习kotlin? Kotlin 早就已经是 Google 官方推荐的开发语言了,而且 Android 新的 Compose 框架只支持 Kotlin ,在 Google 那里,Android开发中 Java 其实已经被淘汰了。Java 和 Kotlin 虽然都属于高级语言,但是 …

LeetCode--2.两数相加

文章目录 1 题目描述2 解题思路2.1 代码实现 1 题目描述 给你两个 非空 的链表, 表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的, 并且每个节点只能存储 一位 数字 请你将两个数相加, 并以相同形式返回一个表示和的链表 你可以假设除了数字 0 之外, 这两个数都…

redis archive github

https://github.com/redis/redis/releases/tag/7.2.2https://github.com/redis/redis/releases/tag/7.2.2