【设计模式】腾讯二面:自动贩卖机/音频播放器使用了什么设计模式?

news2024/9/20 18:36:35

状态模式是什么?

状态模式,也被称作状态对象模式,是一种行为设计模式。

当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。

它让对象在其内部状态改变时改变自己的行为。外部调用者无需了解对象内部状态的具体实现,仅需通过简单的接口进行交互

状态模式适用于哪些场景?

当你的对象基于其状态有不同的行为,并且其状态可以在运行时动态转换时,你应该考虑使用状态模式。

如何在Java中实现状态模式?——自动贩卖机

让我们以一个简单的售卖饮料的自动贩卖机为例,来展示如何在Java中实现状态模式。我们首先定义一个状态接口:

public interface State {
    void insertCoin();
    void pushButton();
    void dispense();
}

然后,我们为自动贩卖机的每一种状态实现该接口:

public class NoCoinState implements State {
    public void insertCoin() {
        // 接收硬币,并转换状态
    }

    public void pushButton() {
        // 提示用户先投币
    }

    public void dispense() {
        // 无行为
    }
}

public class HasCoinState implements State {
    public void insertCoin() {
        // 提示用户已经投过币了
    }

    public void pushButton() {
        // 检查库存,然后转换状态
    }

    public void dispense() {
        // 无行为
    }
}

public class SoldState implements State {
    public void insertCoin() {
        // 提示用户等待饮料出货
    }

    public void pushButton() {
        // 提示用户等待饮料出货
    }

    public void dispense() {
        // 出货,然后转换状态
    }
}

最后,我们实现自动贩卖机类:

public class VendingMachine {
    private State noCoinState;
    private State hasCoinState;
    private State soldState;
    
    private State state;  // 当前状态

    public VendingMachine() {
        noCoinState = new NoCoinState();
        hasCoinState = new HasCoinState();
        soldState = new SoldState();
        
        state = noCoinState;  // 初始状态
    }

    public void insertCoin() {
        state.insertCoin();
    }

    public void pushButton() {
        state.pushButton();
        state.dispense();
    }

    // 其他方法,例如改变状态...
}

这样,我们的自动贩卖机就可以根据自身的状态决定相应的行为,而无需在一个方法中使用大量的条件语句来判断状态。此外,如果未来我们需要添加更多的状态或者行为,我们也可以很容易地进行拓展。

另一个例子——音频播放器

让我们从一个现实生活的例子看一看状态模式如何被运用到音频播放器的开发中。

音频播放器根据用户的操作和播放条件,可能有多种的状态:例如,“播放状态”,“暂停状态”,“停止状态"和"缓冲状态”。不同的状态下,音频播放器的响应行为可能会不同。

首先,定义一个状态接口:

public interface State {
    void play();
    void pause();
    void stop();
    void buffer();
}

然后,实现播放器的每一个状态:

public class PlayingState implements State {
    public void play() {
        // 无响应或提示正在播放
    }

    public void pause() {
        // 暂停播放,并转换到暂停状态
    }

    public void stop() {
        // 停止播放,并转换到停止状态
    }
    
    public void buffer() {
        // 无行为或转到缓冲状态
    }
}

// 类似的,我们还可以定义PauseState、StopState和BufferingState类

在定义了各种状态以后,我们就可以在音频播放器类中使用这些状态:

public class AudioPlayer {
    private State playingState;
    private State pauseState;
    private State stopState;
    private State bufferingState;
    
    private State state;  // 当前状态

    public AudioPlayer() {
        playingState = new PlayingState();
        pauseState = new PauseState();
        stopState = new StopState();
        bufferingState = new BufferingState();
        
        state = stopState;  // 初始状态
    }

    public void play() {
        state.play();
    }

    public void pause() {
        state.pause();
    }
    
    public void stop() {
        state.stop();
    }

    public void buffer() {
        state.buffer();
    }
    
    // 其他方法,例如改变状态...
}

这样,音频播放器就可以根据当前的状态来进行不同的操作,比如在"播放状态"下如果用户按了播放按钮,播放器可以选择无响应或者给出正在播放的提示,而在"暂停状态"下则会恢复播放。这就是状态模式的魅力,使得音频播放器的代码更易于管理和维护。如果我们需要添加新的状态或行为,也可以轻松地进行拓展。希望通过这篇博文,你能对状态模式有更深入的理解和应用。

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

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

相关文章

(蓝桥杯每日一题)love

问题描述 马上就要到七夕情人节了,小蓝在这天想要心爱得男神表白,于是她写下了一个长度为n仅由小写字母组成的字符串。 她想要使这个字符串有 1314个 love 子序列但是马虎的小蓝却忘记了当前已经有多少个子序列为 love。 请你帮小蓝计算出当前字符串有多…

Rustdesk 中VP8 / VP9 / AV1 是什么?

环境: Rustdesk1.1.9 VP8 / VP9 / AV1 问题描述: VP8 / VP9 / AV1 是什么? 解决方案: 1.VP8、VP9和AV1是视频编解码器,用于压缩和解压缩视频数据。它们是由Google和Alliance for Open Media(AOM&#…

spring springfox-swagger2 2.7.0配置

springboot版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version><relativePath/> <!-- lookup parent from repository -->…

解决国内Linux服务器无法使用Github的方法

解决思路&#xff1a;修改Host https://www.ipaddress.com/ 利用上面的网站查询github.com和raw.githubusercontent.com的DNS解析的IP地址 最后&#xff0c;修改服务器的/etc/hosts 添加如下两行&#xff1a; 140.82.112.3 github.com 185.199.108.133 raw.githubuserconte…

Python 中多线程与多处理之间的区别

一、说明 在本文中&#xff0c;我们将学习 Python 中多线程和多处理的内容、原因和方式。在我们深入研究代码之前&#xff0c;让我们了解这些术语的含义。 二、基本术语和概念 程序是一个可执行文件&#xff0c;它由一组执行某些任务的指令组成&#xff0c;通常存储在计算机的…

数据恢复轻松搞定:如何处理.adver的数据勒索

引言&#xff1a; 勒索病毒日益猖獗&#xff0c;.adver 勒索病毒作为新兴威胁之一&#xff0c;给用户的数据安全带来了不小的挑战。本文将深入介绍.adver勒索病毒的特点、被加密数据的恢复方法&#xff0c;以及全面的预防措施&#xff0c;帮助您更好地了解并应对这一数字威胁。…

【每日一题】按分隔符拆分字符串

文章目录 Tag题目来源解题思路方法一&#xff1a;遍历方法二&#xff1a;getline 写在最后 Tag 【遍历】【getline】【字符串】【2024-01-20】 题目来源 2788. 按分隔符拆分字符串 解题思路 方法一&#xff1a;遍历 思路 分隔符在字符串开始和结束位置时不需要处理。 分隔…

16k+ start 一个开源的的监控系统部署教程

安装条件 Linux或macOS系统 4GB内存 开放 33014、33174、3183端口 1.安装 1、下载源码 首先使用 git 克隆源码到本地 git clone -b main https://github.com/SigNoz/signoz.git && cd signoz/deploy/ 方式1&#xff1a;运行 install.sh 脚本一键安装 ./install.s…

HAL库配置RS485通信

在配置好串口的基础上完成RS485的配置 一、使能RS485的发送和接收模式引脚 __HAL_RCC_GPIOG_CLK_ENABLE();//高电平是发送模式&#xff0c;低电平是接收模式&#xff0c;默认是接收模式HAL_GPIO_WritePin(PG4_RS485_DIR1_Port, PG4_RS485_DIR1_Pin, GPIO_PIN_RESET);GPIO_Init…

代码随想录算法训练营Day24 | 122.买卖股票的最佳时期、55.跳跃游戏、45.跳跃游戏||

LeetCode 122 买卖股票的最佳时期 本题思路&#xff1a;记录每天的利润值&#xff0c;第一天的为 0 &#xff0c;第二天的当天的减去前一天的。然后遍历相加为正的利润值。最后得到的结果就是最大利润。 class Solution {public int maxProfit(int[] prices) {int res 0;for(…

DiffMIC:融合局部和全局分析,基于扩散模型的医学图像分类方法

DiffMIC&#xff1a;基于扩散模型的医学图像分类方法 DiffMIC的核心思想糖尿病视网膜病变分级 网络结构去噪扩散模型&#xff1a;提升特征清晰度双粒度条件引导&#xff08;DCG&#xff09;&#xff1a;融合局部和全局分析条件特定的最大均值差异&#xff08;MMD&#xff09;正…

Linux:软件包管理器 yum

提示&#xff1a;以下指令均在Xshell 7 中进行 什么是软件包&#xff1f; 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序。 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安 装程序)放…

Linux上软件安装

软件安装常见方式 二进制发布包 软件已经针对具体平台编译打包发布&#xff0c;只要解压&#xff0c;修改配置即可。 RPM包 软件已经按照redhat的包管理工具规范RPM进行打包发布&#xff0c;需要获取到相应的软件RPM发布包&#xff0c;然后用RPM命令进行安装&#xff0c;但…

Internet Download Manager 6.42.3 (IDM) 中文破解免激活绿色版

Internet Download Manager 6.42.3中文破解版&#xff0c;全球最佳下载利器。Internet Download Manager (简称IDM) 是一款Windows 平台功能强大的多线程下载工具&#xff0c;国外非常受欢迎。支持断点续传&#xff0c;支持嗅探视频音频&#xff0c;接管所有浏览器&#xff0c;…

可视化k8s页面(Kubepi)

Kubepi是一个简单高效的k8s集群图形化管理工具&#xff0c;方便日常管理K8S集群&#xff0c;高效快速的查询日志定位问题的工具 随便在哪个节点部署&#xff0c;我这里在主节点部署 docker pull kubeoperator/kubepi-server docker run --privileged -itd --restartunless-st…

动态规划汇总

作者推荐 视频算法专题 简介 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;是运筹学的一个分支&#xff0c;是求解决策过程最优化的过程。每次决策依赖于当前状态&#xff0c;又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的&#x…

端杂七杂八系列篇四-Java8篇

后端杂七杂八系列篇四-Java8篇 ① Lombok插件① RequiredArgsConstructor② SneakyThrows③ UtilityClass④ Cleanup ② Lambda 4个常用的内置函数① Function<T, R> - 接受一个输入参数并返回一个结果② Consumer - 接受一个输入参数&#xff0c;并执行某种操作&#xf…

Jumpserver中安装httpx

查看已安装的包 pip freeze # python -V # Python 2.7.5安装anyio 刚开始直接pip install httpx&#xff0c;未设置版本号&#xff0c;因已有idna2.7&#xff0c;所以出现版本不兼容的现象 anyio 3.0.0 requires idna>2.8, but you have idna 2.7 which is incompatible.…

Red Hat Enterprise Linux 8.9 安装图解

引导和开始安装 选择倒计时结束前&#xff0c;通过键盘上下键选择下图框选项&#xff0c;启动图形化安装过程。需要注意的不同主板默认或者自行配置的固件类型不一致&#xff0c;引导界面有所不同。也就是说使用UEFI和BIOS的安装引导界面是不同的&#xff0c;如图所示。若手动调…

【VRTK】【Unity】【游戏开发】项目实践-小游戏

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【背景】 本篇做一个综合实践,应用所学做一个mini VR游戏。不用写一行代码,纯粹理解并使用现有的VRTK脚本。 【导入所需资源】 在之前VRTK项目基础上…