【行为型模式】状态模式

一、状态模式概述

        状态模式的定义:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。(对象行为型)

策略模式和状态模式是双胞胎,在出生时才分开。

  • 策略模式是围绕可以互换的算法来创建成功业务的。
  • 状态模式走的是更崇高的路,它通过改变对象内部的状态来帮助对象控制自己的行为。
  • 状态模式的优缺点
    • 优点
      • 1.可以将不同的状态隔离;
      • 2.每个状态都是一个单独的类;
      • 3.可以将各种状态的转换逻辑 , 分布到状态的子类中 ,减少相互依赖;
      • 4.增加新状态操作简单。
    • 缺点
      • 如果状态数量比较多,状态类的数量会增加,业务场景系统变得很复杂;
      • 如果业务中某个对象由几十上百个状态,就会很复杂,这时就需要对状态进行拆分处理。
  • 适用场景
    • 一个对象存在多个状态,状态可以相互转换;
    • 不同状态下,行为不同。

二、代码实现

        状态模式主要包含三个角色:

  • 环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理;
  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为;
  • 具体状态(Concrete State)角色:实现抽象状态所对应的行为。
        2.1 环境角色(GumballMachine)
package state.CandySolder;
//环境角色
public class GumballMachine {private State noQuarterState;private State hasQuarterState;private State soldState;private State soldOutState;private State state = soldOutState; // 糖果机默认状态为售罄状态int count = 0; // 糖果库存量public GumballMachine(int numberGumballs) {noQuarterState = new NoQuarterState(this);hasQuarterState = new HasQuarterState(this);soldState = new SoldState(this);soldOutState = new SoldOutState(this);count = numberGumballs;if (numberGumballs > 0) {state = noQuarterState; // 如果采购了糖果球(numberGumballs>0),则糖果机的状态为未投币状态}}// 投入钱币public void insertQuarter() {state.insertQuarter();}// 退出钱币public void ejectQuarter() {state.ejectQuarter();}// 扭转曲柄public void turnCrank() {state.turnCrank();state.dispense();}// 减少库存public void releaseBall() {if (count > 0) {System.out.println("一个糖果球正在出库");--count;} else {System.out.println("库存不足,一个糖果球无法出库");}}// 设置状态void setState(State state) {this.state = state;}//get,set方法public State getNoQuarterState() {return noQuarterState;}public State getSoldOutState() {return soldOutState;}public void setSoldOutState(State soldOutState) {this.soldOutState = soldOutState;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public void setNoQuarterState(State noQuarterState) {this.noQuarterState = noQuarterState;}public State getHasQuarterState() {return hasQuarterState;}public void setHasQuarterState(State hasQuarterState) {this.hasQuarterState = hasQuarterState;}public State getSoldState() {return soldState;}public void setSoldState(State soldState) {this.soldState = soldState;}}
        2.2 抽象状态(State)
package state.CandySolder;
//抽象角色
public interface State {void insertQuarter(); // 投入硬币操作   void ejectQuarter(); // 退出硬币操作void turnCrank(); // 扭转曲柄操作void dispense(); // 发放糖果操作
}
        2.3 具体状态(HasQuarterState、NoQuarterState、SoldOutState、SoldState)
package state.CandySolder;
//具体状态,已经投放钱币状态
public class HasQuarterState implements State {private GumballMachine gumballMachine;public HasQuarterState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("您已经投入钱币!无须再次投入钱币!");}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("退款成功!");gumballMachine.setState(gumballMachine.getNoQuarterState()); // 状态流转}@Overridepublic void turnCrank() {// TODO Auto-generated method stubSystem.out.println("正在出货中,请稍等");gumballMachine.setState(gumballMachine.getSoldState()); // 状态流转}@Overridepublic void dispense() {// TODO Auto-generated method stubSystem.out.println("你还没有扭转曲柄,糖果不可以发放!");}}
package state.CandySolder;
//具体状态,没有投放钱币状态
public class NoQuarterState implements State {private GumballMachine gumballMachine;public NoQuarterState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("投入钱币成功!");gumballMachine.setState(gumballMachine.getHasQuarterState()); // 状态流转}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("你还没有投入钱币,不能退回钱币!");}@Overridepublic void turnCrank() {// TODO Auto-generated method stubSystem.out.println("你还没有投入钱币,不能扭转曲柄!");}@Overridepublic void dispense() {// TODO Auto-generated method stubSystem.out.println("你还没有投入钱币,糖果不可以发放!");}}
package state.CandySolder;
//具体状态,糖果售空状态
public class SoldOutState implements State {private GumballMachine gumballMachine;public SoldOutState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("糖果已经售罄。不能投入钱币");}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("退回钱币成功!");}@Overridepublic void turnCrank() {// TODO Auto-generated method stubSystem.out.println("糖果已经售罄。不能扭转曲柄!");}@Overridepublic void dispense() {// TODO Auto-generated method stubSystem.out.println("糖果已经售罄。糖果无法出售!");}}
package state.CandySolder;
//具体状态,糖果售卖状态
public class SoldState implements State {private GumballMachine gumballMachine;public SoldState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("糖果正在出货中,请稍等。无须再次投入钱币!");}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("糖果正在出货中,请稍等。不能退回钱币!");}@Overridepublic void turnCrank() {// TODO Auto-generated method stubSystem.out.println("糖果正在出货中,请稍等。不需要再次扭转曲柄!");}@Overridepublic void dispense() {// TODO Auto-generated method stubif (gumballMachine.getCount() > 0) {System.out.println("糖果正在出货中,请稍等!");gumballMachine.releaseBall();gumballMachine.setState(gumballMachine.getNoQuarterState()); // 状态流转} else {System.out.println("糖果库存不足,无法出货!");gumballMachine.setState(gumballMachine.getSoldOutState()); // 状态流转}}}
        2.4 main方法实现状态模式
package state.CandySolder;
//测试
public class Test {public static void main(String[] args) {System.out.println("-----向糖果机中放入1枚糖果-----");GumballMachine machine = new GumballMachine(1);System.out.println("-----第一次购买糖果-----");machine.insertQuarter();machine.ejectQuarter();machine.turnCrank();System.out.println("-----第二次购买糖果-----");machine.insertQuarter();machine.turnCrank();System.out.println("-----第三次购买糖果-----");machine.insertQuarter();machine.turnCrank();machine.ejectQuarter();}
}
        2.5 UML图

三、代码结构图

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

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

相关文章

全民拼购:社交电商与拼购玩法的完美结合

大家好,我是微三云周丽,今天给大家分析当下市场比较火爆的商业模式! 小编今天跟大伙们分享什么是社交电商与拼购玩法的wan美结合? 随着社交电商和拼购玩法的兴起,全民拼购模式正逐渐成为电商行业的新宠。结合了人性化…

CSS中的display: flex;

display: flex; 是CSS(层叠样式表)中用于设置容器为弹性盒子模型(Flexbox)的属性值。弹性盒子模型是CSS3中引入的一个新的布局模式,它设计用来更好地在容器中布局、对齐和分配空间给子元素(即容器内的项目&…

Github账号注册

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

深度学习与神经网络入门

前言 人工智能(AI)与机器学习(ML)与深度学习(DL)的关系: DL包含于ML,ML包含于AI。 即深度学习是机器学习一部分,机器学习又是人工智能的一个分支。 那么深度学习到底有…

运气变好的几个小妙招

首先不要总是说一些丧气话,因为老天爷是听不到主语的,即使你当时说的是”谁谁谁好烦人啊“类似的句式,但传到上帝耳朵的时候会失去主语,也就会潜移默化的带到自己身上。 那我们应该怎么做呐? 1. 避免消极语言 首先&…

本文为解决:前端json传String格式时间参数,后端无法解析。

有的人说单独写一个localDateTime配置类,看了一下可以不用。 直接写WebMvcConfig里面就行 import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToS…

CSS flex弹性布局属性

容器属性 flex-direction 设置主轴方向,默认水平方向 row 默认值,主轴为水平方向(从左向右排水平布局) row-reverse 主轴为水平方向(从右向左排水平布局) column 主轴为垂直方向(从上到下垂直布局&#x…

学习笔记——微信小程序var与let、bindtap与bindinput、全局变量与局部变量的区别

1、var与let的区别 var申明的为全局变量,作用域为所在的函数内,其他函数调用会出现变量未定义的报错 let声明的为局部变量,只会作用于最近的{}中,其他区域无法调用 2、全局变量与局部变量 全局变量是在整个小程序运行周期内都…

openGauss学习笔记-268 openGauss性能调优-TPCC性能调优测试指导-网络配置-网卡多中断队列设置

文章目录 openGauss学习笔记-268 openGauss性能调优-TPCC性能调优测试指导-网络配置-网卡多中断队列设置268.1 中断调优268.2 网卡固件确认与更新 openGauss学习笔记-268 openGauss性能调优-TPCC性能调优测试指导-网络配置-网卡多中断队列设置 本章节主要介绍openGauss数据库内…

B203-若依框架应用

目录 简介版本RuoYi-fast项目准备新增模块/代码生成 简介 基于SpringBoot的权限管理系统,基于SpringBoot开发的轻量级Java快速开发框架 版本 前后端未分离单应用版本:RuoYi-fast,前后端未分离多模块版本:RuoYi 前后端分离单应用…

转行做银行测试,需要了解哪些?

在这个内卷严重的时代,银行的业务不断增加,随着软件信息化的要求越来越高,银行对软件测试人员也提出了非常高的要求。 银行的软件测试是针对银行的软件系统(如柜面系统、信贷系统)和银行专用设备(如ATM机、…

浅谈薪酬绩效设计及运行的忌讳

薪酬绩效设计及运行是企业管理中的重要环节,直接关系到员工的工作积极性和企业的整体效益。然而,在实际操作中,许多企业往往因为对薪酬绩效设计的不当理解或操作不当,导致了一系列问题的出现。本文将从薪酬绩效设计及运行的忌讳入…

一键还原精灵 V12.1.405.701 装机版

网盘下载 个人版:不划分分区不修改分区表及MBR,安装非常安全,备份文件自动隐藏,不适用于WIN98系统。 装机版:需用PQMAGIC划分分区作隐藏的备份分区,安装过程中有一定的风险,安装后就非常安全。…

基于Spring Cloud Alibaba的微服务业务拆分设计

胡弦,视频号2023年度优秀创作者,互联网大厂P8技术专家,Spring Cloud Alibaba微服务架构实战派(上下册)和RocketMQ消息中间件实战派(上下册)的作者,资深架构师,技术负责人,极客时间训练营讲师,四…

2024年4月22号PMP每日三题含答案

2024年4月22号PMP每日三题含答案 1.项目经理正在执行一个涉及不同业务部门的全公司项目。在一次规划会议上,项目经理注意到每个部门的具体需求不能引起其他部门的兴趣,这影响到会议的质量。 若要解决这个问题,项目经理应该怎么做&#xff1f…

Javascript设计模式 -- 发布订阅模式

发布订阅模式 发布订阅模式是一种对象之间一对多的依赖关系(利用消息队列) 当一个对象的状态发生变化,所有依赖它的对象都会得到状态改变的通知 订阅者把自己想订阅的事件注册到调度中心 发布者发布该事件到调度中心,当该事件触发的时候,会由…

Dockerfile学习

一、基础知识 0、参考:Dockerfile 指令详解 | Docker — 从入门到实践 1、Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。 …

CentOS8安装更换JDK

CentOS8安装更换JDK 背景:在服务器上启动java项目报错,JDK问题。更换jdk。探索整理安装JDK的方法。一些常用系统命令。清华源下载。 文章目录 CentOS8安装更换JDK准备工作:查看本地相关信息 方式一:yum安装搜索安装配置环境变量 方…

three.js实现热力图(vue heatmap.js)

vuethree.js项目 heatmap.js这个库太久没维护了,换别人二开的库rengr/heatmap.js npm i rengr/heatmap.js使用方式与heatmap.js这个库一样 heatmap.js参考文档 import h337 from rengr/heatmap.js function addHeatmapPlane() {let x 230let y 60const canvas…

Linux(rpm,yum安装及管理程序)

目录 1.应用程序与系统命令 2.RPM 2.1rpm软件包管理工具 2.2 rpm命令的形式 2.3查询rpm软件包 ​2.4安装、升级、卸载rpm软件包 2.5维护数据库 3.yum 3.1 配置本地yum源仓库 3.2 yum常用操作命令 3.3 源码编译安装软件 1.应用程序与系统命令 应用程序与系统命令的关系 典…