状态设计模式的替代方案

问题描述 投票:0回答:1

所以我一直在阅读 refactoring.guru 上的一些设计模式,并且对行为设计模式特别感兴趣。

但是,有一种设计模式让我质疑它是否将单一职责原则走得太远:State 模式。

此外,各州应该依赖于每个州的事实让我想知道把它们放在不同的班级里到底是不是个好主意。

让我们以他们网站上给出的例子为例:音频播放器。 这是伪代码:

// The AudioPlayer class acts as a context. It also maintains a
// reference to an instance of one of the state classes that
// represents the current state of the audio player.
class AudioPlayer is
    field state: State
    field UI, volume, playlist, currentSong

    constructor AudioPlayer() is
        this.state = new ReadyState(this)

        // Context delegates handling user input to a state
        // object. Naturally, the outcome depends on what state
        // is currently active, since each state can handle the
        // input differently.
        UI = new UserInterface()
        UI.lockButton.onClick(this.clickLock)
        UI.playButton.onClick(this.clickPlay)
        UI.nextButton.onClick(this.clickNext)
        UI.prevButton.onClick(this.clickPrevious)

    // Other objects must be able to switch the audio player's
    // active state.
    method changeState(state: State) is
        this.state = state

    // UI methods delegate execution to the active state.
    method clickLock() is
        state.clickLock()
    method clickPlay() is
        state.clickPlay()
    method clickNext() is
        state.clickNext()
    method clickPrevious() is
        state.clickPrevious()

    // A state may call some service methods on the context.
    method startPlayback() is
        // ...
    method stopPlayback() is
        // ...
    method nextSong() is
        // ...
    method previousSong() is
        // ...
    method fastForward(time) is
        // ...
    method rewind(time) is
        // ...


// The base state class declares methods that all concrete
// states should implement and also provides a backreference to
// the context object associated with the state. States can use
// the backreference to transition the context to another state.
abstract class State is
    protected field player: AudioPlayer

    // Context passes itself through the state constructor. This
    // may help a state fetch some useful context data if it's
    // needed.
    constructor State(player) is
        this.player = player

    abstract method clickLock()
    abstract method clickPlay()
    abstract method clickNext()
    abstract method clickPrevious()


// Concrete states implement various behaviors associated with a
// state of the context.
class LockedState extends State is

    // When you unlock a locked player, it may assume one of two
    // states.
    method clickLock() is
        if (player.playing)
            player.changeState(new PlayingState(player))
        else
            player.changeState(new ReadyState(player))

    method clickPlay() is
        // Locked, so do nothing.

    method clickNext() is
        // Locked, so do nothing.

    method clickPrevious() is
        // Locked, so do nothing.


// They can also trigger state transitions in the context.
class ReadyState extends State is
    method clickLock() is
        player.changeState(new LockedState(player))

    method clickPlay() is
        player.startPlayback()
        player.changeState(new PlayingState(player))

    method clickNext() is
        player.nextSong()

    method clickPrevious() is
        player.previousSong()


class PlayingState extends State is
    method clickLock() is
        player.changeState(new LockedState(player))

    method clickPlay() is
        player.stopPlayback()
        player.changeState(new ReadyState(player))

    method clickNext() is
        if (event.doubleclick)
            player.nextSong()
        else
            player.fastForward(5)

    method clickPrevious() is
        if (event.doubleclick)
            player.previous()
        else
            player.rewind(5)

代码中的状态是相互依赖的。它有点像破损的封装,虽然它看起来确实比将所有方法都放在 AudioPlayer 本身中更好的解决方案,但我仍然觉得会有更好的方法来设计整个 Audio-Player 项目本身。

当我将其与 Strategy 设计模式进行比较时,所有策略都相互不了解,我发现状态模式非常缺乏,就像它对可读性没有多大帮助。我知道用例有很大不同,但是 Strategy 模式让我想知道是否有更好的方法来设置 Audio-Player 类,以便我们可以使用 State 模式以外的东西。

所以我的问题是,状态设计模式的最佳直接替代方案是什么? 此外,设置 Audio-Player 类以便它可以使用其他设计模式的最佳方法是什么?

oop design-patterns solid-principles strategy-pattern state-pattern
1个回答
0
投票

代码中的状态是相互依赖的。它有点像破损的封装,虽然它看起来确实比将所有方法都放在 AudioPlayer 本身更好的解决方案

我相信如果我们将所有方法放在一个类中,那么有必要使用多个

if else
语句来定义单击按钮时应该做什么。 支持这些多个
if else
语句似乎完全是一场噩梦,但如果我们将一个行为封装在一个类中,那么我们应该只编辑一个类,它符合开放/封闭原则。所以,在我看来,状态设计模式是适用于当前案例的合适设计模式,因为

  • 它将行为封装在类中。因此,如果有必要编辑行为,那么您将在课堂上进行编辑,而不会潜入
    if else
    陈述,并且担心
    if else
    陈述可能被错误评估
  • 符合开/闭原则
  • 它减少了
    if else
    语句的数量
© www.soinside.com 2019 - 2024. All rights reserved.