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

状态模式是什么?

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

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

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

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

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

如何在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();
    }
    
    // 其他方法,例如改变状态...
}

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

相关推荐
GISer_Jing1 分钟前
Vue3常见Composition API详解(适用Vue2学习进入Vue3学习)
前端·javascript·vue.js
Dragon Wu7 分钟前
TailwindCss 总结
前端·css·前端框架
春风十里不如你952715 分钟前
【设计模式】【行为型模式(Behavioral Patterns)】之命令模式(Command Pattern)
设计模式·命令模式
bpmf_fff17 分钟前
十、事件类型(鼠标事件、焦点.. 、键盘.. 、文本.. 、滚动..)、事件对象、事件流(事件捕获、事件冒泡、阻止冒泡和默认行为、事件委托)
前端·javascript
计算机学姐19 分钟前
基于SSM的宠物领养平台
java·vue.js·spring·maven·intellij-idea·mybatis·宠物
泰山小张只吃荷园30 分钟前
期末Python复习-输入输出
java·前端·spring boot·python·spring cloud·docker·容器
Mr_Xuhhh32 分钟前
程序地址空间
android·java·开发语言·数据库
YSRM38 分钟前
异或-java-leetcode
java·算法·leetcode
大明湖的狗凯.41 分钟前
MySQL 中的乐观锁与悲观锁
java·数据库·mysql
z202305081 小时前
linux之调度管理(13)- wake affine 唤醒特性
java·开发语言