【重温设计模式】状态模式及其Java示例

状态模式的基本概念

在编程世界的大海中,各种设计模式就如同灯塔,为我们的代码编写指明方向。其中,状态模式是一种行为设计模式,它让你能在一个对象的内部状态改变时改变其行为,使得对象看起来就像改变了其类一样。这个模式的名字,仿佛是在告诉我们,它就像一个小船,在程序设计的海洋中,根据风向(状态)改变航向(行为)。

状态模式在面向对象设计中的重要性不言而喻,它是我们处理复杂对象状态转换,减少条件语句,使代码更加清晰和易于维护的重要工具。

public class OneMore {private State state;public OneMore(State state) {this.state = state;}public void setState(State state) {this.state = state;}public void request() {state.handle(this);}
}

在这段简单的Java代码中,我们定义了一个名为OneMore的类,这个类有一个状态(State)属性,通过改变这个状态,OneMore的行为也会随之改变。这就是状态模式的基本概念和应用。不过,要想深入理解和灵活运用状态模式,我们还需要了解其内部的结构和组成。

状态模式的结构和组成

在了解了状态模式的基本概念之后,我们来深入探讨一下它的结构和组成。状态模式主要由三个部分组成:上下文(Context)、抽象状态(Abstract State)和具体状态(Concrete State)。

首先,我们来看一下上下文。上下文是一个定义客户端所感兴趣的接口,并且维护一个具体状态类的实例,这个实例定义了当前的状态。上下文可以对外提供一种接口,用于改变它的状态。

然后,我们来看看抽象状态。抽象状态定义了一个接口,用于封装与上下文的一个特定状态相关的行为。在抽象状态中,我们可以定义一些方法,这些方法可以被不同的具体状态所重写,以实现不同状态下的行为。

最后,我们来看看具体状态。具体状态是抽象状态的子类,每一个子类实现了一个与上下文的状态相关的行为。在具体状态中,我们可以实现抽象状态中定义的方法,以实现不同状态下的行为。

下面是一个简单的Java代码示例,用于展示状态模式的结构和组成:

class Context {private AbstractState state;public void setState(AbstractState state) {this.state = state;}public void request() {state.handle(this);}
}abstract class AbstractState {abstract void handle(Context context);
}class ConcreteStateA extends AbstractState {void handle(Context context) {System.out.println("Handle in state A");context.setState(new ConcreteStateB());}
}class ConcreteStateB extends AbstractState {void handle(Context context) {System.out.println("Handle in state B");context.setState(new ConcreteStateA());}
}class OneMoreClass {public static void main(String[] args) {Context context = new Context();context.setState(new ConcreteStateA());context.request();context.request();}
}

在这个例子中,我们定义了一个名为OneMoreClass的类,用于展示状态模式的使用。在OneMoreClass类的main方法中,我们创建了一个Context对象,并通过setState方法设置了初始状态为ConcreteStateA,然后通过request方法触发状态转换。

contains
1
1
extends
extends
uses
Context
-AbstractState state
+setState(AbstractState state)
+request()
«abstract»
AbstractState
+handle(Context context)
ConcreteStateA
+handle(Context context)
ConcreteStateB
+handle(Context context)
OneMoreClass
+main(args)

通过这样的结构和组成,状态模式可以让我们的代码更加清晰,更加易于理解和维护。接下来,我们将通过一个互联网电子商务项目中的Java实例,进一步展示如何实现状态模式。

状态模式的Java实例

在前面,我们已经对状态模式的基本概念和结构有了一定的了解。现在,让我们通过一个具体的Java实例来看看如何在实际项目中实现状态模式。假设我们正在开发一个互联网电子商务项目,其中有一个Order订单类,订单的状态有多种,比如新订单、已支付、已发货等,每种状态下订单的行为也各不相同。

首先,我们需要定义一个上下文类,也就是订单类Order。这个类中维护了一个State状态对象,这个State对象定义了订单在当前状态下的行为。

public class Order {private State state;public void setState(State state) {this.state = state;}public void behavior() {this.state.behavior();}
}

接着,我们定义一个抽象状态类State,这个类定义了所有状态共有的行为接口。

public abstract class State {public abstract void behavior();
}

然后,我们根据订单的实际状态,定义出多个具体的状态类,比如NewOrderStatePaidStateDeliveredState等。这些类继承自State抽象状态类,并实现了behavior方法,定义了在该状态下订单的行为。

public class NewOrderState extends State {@Overridepublic void behavior() {System.out.println("新订单,等待支付");}
}public class PaidState extends State {@Overridepublic void behavior() {System.out.println("已支付,等待发货");}
}public class DeliveredState extends State {@Overridepublic void behavior() {System.out.println("已发货,等待收货");}
}

这样,我们就实现了一个简单的状态模式。在实际的使用中,只需要改变Order订单对象的状态,就可以改变订单的行为。而且,如果需要增加新的状态,只需要增加新的状态类即可,无需修改Order类,符合开闭原则。

contains
1
1
extends
extends
extends
Order
-State state
+setState(State state)
+behavior()
«abstract»
State
+behavior()
NewOrderState
+behavior()
PaidState
+behavior()
DeliveredState
+behavior()

然而,虽然状态模式有许多优点,但也存在一些缺点,接下来我们将详细探讨状态模式的优缺点。

状态模式的优缺点

在前面,我们已经通过一个具体的Java例子详细地介绍了状态模式的实现过程,现在我们来讨论一下状态模式的优缺点,以及它在实际开发中的应用场景。

首先,让我们来看看状态模式的优点。一大优点就是它能够减少系统中的条件语句。在传统的程序设计中,我们通常会使用if-else或者switch-case语句来处理对象的状态转换,但这样做的问题是,随着状态的增多,条件语句也会越来越复杂,这对于代码的可读性和可维护性都是一种负面影响。而状态模式能够将每个状态的行为封装在一个类中,通过改变对象的状态来改变其行为,从而避免了复杂的条件语句。

其次,状态模式非常易于扩展。当我们需要添加一个新的状态时,只需要定义一个新的状态类即可,无需修改原有的代码,这符合了开闭原则。

然而,状态模式也有其缺点。那就是状态类的数量可能会过多,尤其是在状态非常复杂的情况下。每一个状态都对应一个状态类,这会导致系统中类的数量增多,增加了系统的复杂性。

至于状态模式的适用场景,一般来说,当一个对象的行为依赖于其状态,并且它需要在运行时刻改变其行为时,就可以考虑使用状态模式。例如,在电商平台中,订单的状态有多种,如待支付、已支付、待发货、已发货、已完成等,每种状态下订单的行为都是不同的,这就是一个典型的状态模式的应用场景。

总的来说,状态模式是一种非常实用的设计模式,它能够帮助我们更好地管理和控制对象的状态转换,提高代码的可读性和可维护性。但我们也要注意避免状态类的过度增多,使得系统过于复杂。

总结

在这个编程的海洋中,状态模式就像一艘小船,它能够根据风向(状态)改变航向(行为),让我们的代码更加清晰、易于理解和维护。它是我们处理复杂对象状态转换,减少条件语句的重要工具。但是,我们也要注意,每一个状态都对应一个状态类,这可能会导致状态类的数量过多,增加系统的复杂性。因此,我们在使用状态模式时,既要看到它的优点,也要注意它的缺点,恰如其分地使用,才能真正提高我们的代码质量。

在我们的编程生涯中,我们会遇到各种各样的设计模式,就像在海洋中遇到的各种各样的风向。有的风向会帮助我们顺利前行,有的风向则可能会让我们迷失方向。但无论如何,我们都要有勇气去面对,有智慧去选择,因为这就是编程,这就是我们的生活。

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

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

相关文章

Git小乌龟安装及使用教程

一、Win7安装git 软件下载地址:git for windows 安装过程直接默认下一步,直到安装结束。 安装结束后重启一下。 安装完成后,在文件夹空白处右键出现以下几个标识,说明安装成功。 二、安装tortoise git(乌龟git&…

分布式砖题

雪花算法 变动位数,性能佳,灵活调整bit位划分,灵活 zk 临时节点和watch机制实现注册中心 ,数据都在内存,nio 多线程模型; cp注重一致性,集群数据不一致时集群不可用 数据一致性模型 cap 强…

图解CodeWhisperer的安装使用

🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️ 生活的理想,就是为了理想的生活 ! ​ 目录 📘 CodeWhisperer简介 &#…

力扣202. 快乐数

思路:用一个set记录是否重复出现过某值,是 则是无限循环,不可能还有1的情况,直接返回false; 否则一直处理生产新的数,直到为1; class Solution {public boolean isHappy(int n) {//set记录是否重复出现过某…

内存条@电脑支持的最大内存@升级内存硬件

文章目录 电脑支持的最大内存规格cpu官网查看支持的规格命令行查看脚本化 DDR内存LPDDR内存内存升级扩展👺插槽检查板载内存SPD内存厂商其他 内存参数👺性能指标使用软件查看更多内存相关的软件工具 电脑支持的最大内存规格 确认电脑最大支持内存大小和频…

自动化部署利器:Jenkins+Gitlab助力Springboot项目快速上线,实现持续集成与持续交付!

Jenkins 能干什么 来自官网 官网 Jenkins怎么用【Linux版】 下载 war包 本机为Java8 选择Jenkins版本为2.289.1 注意: 如果是Java8 尽量和我的Jenkins版本保持一致哈!后面可能会遇到各种坑。 把下载好的war放到Linux服务器的某一个目录下 启动war …

python沧州市人民医院患者就诊信息管理系统flask-django-nodejs-php

因此,本论文旨在探讨人民医院患者就诊信息管理系统的建设与实施,分析其在医疗服务中的作用和意义,进一步探讨如何优化医院信息系统和提高医疗服务质量。通过对人民医院患者就诊信息管理系统的研究,可以为医院信息化建设提供借鉴和…

面试笔记——Redis(双写一致、持久化)

双写一致 双写一致性: 当修改了数据库中的数据,也要更新缓存的数据,使缓存和数据库中的数据保持一致。 相关问题:使用Redis作为缓存,mysql的数据如何与Redis进行同步?——双写一致性问题 回答时&#xff0…

Vue 计算属性和监视属性

Vue 计算属性和监视属性 computed computed 计算属性 规则: 用已有的属性计算不存在的属性默认调用一次get()只有值不发生改变的时候才可以使用简写(函数);值发生改变 使用对象式写法,才可以配置set()方法底层原理使…

[项目设计]基于websocket实现网络对战五子棋

项目介绍 该项目旨在实现一个网页端的在线五子棋,将实现登陆、好友、房间、对战、观战、聊天等功能 完成该项目需要了解C、数据库MySQL、基础前端HTML/CSS/JS/Ajax、网络协议WebSocket 项目源码:azhe1/online_gobang - 码云 - 开源中国 (gitee.com) …

R语言实现多要素偏相关分析

偏相关分析是指当两个变量同时与第三个变量相关时,将第三个变量的影响剔除,只分析另外两个变量之间相关程度的过程,判定指标是相关系数的R值。 在GIS中,偏相关分析也十分常见,我们经常需要分析某一个指数与相关环境参…

网络基础知识-DNS与DHCP+网络规划与设计故障诊断+嵌入式系统设计师备考笔记

0、前言 本专栏为个人备考软考嵌入式系统设计师的复习笔记,未经本人许可,请勿转载,如发现本笔记内容的错误还望各位不吝赐教(笔记内容可能有误怕产生错误引导)。 本章的主要内容见下图: 本章知识和计算机…

MNN createSession 之创建流水线后端(四)

系列文章目录 MNN createFromBuffer(一) MNN createRuntime(二) MNN createSession 之 Schedule(三) MNN createSession 之创建流水线后端(四) MNN Session::resize 之流水线编码&am…

B站python爬虫课程笔记(Q16-)

下面是学习的网址: ​​​​​​【Python爬虫】 16、捕捉异常try&except语句的一些问题 1)一些常见的异常类型 IndexError索引错误ZeroDivisionError除零错误FileNotFindError找不到文件错误TypeError类型错误KeyError键错误ValueError值错误Ind…

微信小程序 canvas层级过高覆盖原生组件

一、背景 微信小程序中使用signature第三方插件完成签名效果&#xff0c;但真机调试时发现canvas层级过高遮挡了按钮 二、具体问题 问题原因&#xff1a;签名后点击按钮无法生效 问题代码&#xff1a; <template><view class"sign_page" v-cloak>&l…

51单片机学习笔记7 串转并操作方法

51单片机学习笔记7 串转并操作方法 一、串转并操作简介二、74HC595介绍1. **功能**&#xff1a;2. **引脚**&#xff1a;3. **工作原理**&#xff1a;4. 开发板原理图&#xff08;1&#xff09;8*8 LED点阵&#xff1a;&#xff08;2&#xff09;74HC595 串转并&#xff1a; 三…

蓝桥杯刷题|03普及-真题

[蓝桥杯 2017 省 B] k 倍区间 题目描述 给定一个长度为 N 的数列&#xff0c;​,,⋯&#xff0c;如果其中一段连续的子序列 ​,,⋯ (i≤j) 之和是 K 的倍数&#xff0c;我们就称这个区间 [i,j] 是 K 倍区间。 你能求出数列中总共有多少个 K 倍区间吗&#xff1f; 输入格式 …

Spark 3.5.0 特性速览

介绍 Spark 3系列已经发布了第六版3.5.0&#xff0c;目前最新3.5.1。 使用最广泛的大数据可扩展计算引擎。数以千计的公司&#xff0c;包括 80% 的财富 500 强企业&#xff0c;都在使用 Apache Spark。来自业界和学术界的 2000 多名开源项目贡献者。 Apache Spark 3.5.0 是…

抖音视频爬虫提取工具界面|视频批量下载软件

抖音视频爬虫界面解析 一&#xff1a;概述 抖音视频爬虫是一款功能强大的工具&#xff0c;主要提供关键词批量提取视频和单独视频提取的功能&#xff0c;并支持提取后的视频下载操作。 二&#xff1a;功能解析 2.1&#xff1a;关键词批量提取视频的解析 用户可以通过输入关键…

Kotlin中单例模式和Java的对比浅析

前言 单例模式&#xff0c;一直以来是我们在日常开发中最常用的一种设计模式&#xff0c;更是面试中非常重要&#xff0c;也非常容易被问到的问题。在日常开发中&#xff0c;大家常用的语言还是Java&#xff0c;但今天我给大家带来的是在Kotlin语言中&#xff0c;单例模式是怎…