【问题标题】:How to apply State pattern and strategy pattern together?如何同时应用状态模式和策略模式?
【发布时间】:2018-02-19 06:41:25
【问题描述】:

我需要用 Java 实现一个播放和录制视频的应用程序。
视频播放器有两种状态,Playing moderecording mode
在播放模式下,我们可以Play, Pause,Stop, ForwardBackward视频。
另一方面,在录制模式下,我们可以做到Record, PauseStop
这是我到目前为止所做的:br> 我有点卡住了。我不知道我是否应该为每种模式的每个动作创建一个策略,或者我是否可以让它变得更简单。
我正在考虑为PlayingModeVideoPlayerRecordingModeVideoPlayer 提供它们的特定策略(多个),但我不知道如何实现它。 谢谢
播放和录制模式是两个独立的东西。我不需要实现这两个实体之间的转换。

【问题讨论】:

  • record() 在播放模式下有意义吗?
  • @user7 不,您要么处于播放模式,要么处于录制模式。为了测试它,我将不得不在其中一个实例中创建。
  • 组合继承怎么样?你知道,在初始化你的具体视频播放器时,它们的合法性将是什么。为每个具体的视频播放器构造函数提供一个包含合法入门的 DS。当更改视频播放器的状态时,您可以添加一个对您的具体视频播放器都有效的抽象方法实现 - 验证设置的 startegy 是合法的。
  • this is an exercise to pratice OCP. -- 我觉得你的问题太简单了。 OCP 将来需要另一种策略。到目前为止,播放和录音是有意义的,但第三个是什么?我认为将 OCP 应用于没有真正扩展的问题并不是一个好主意。至于状态,它有结果Because all state-specific code lives in a State subclass, new states and transitions can be added easily by defining new subclasses. 这并不完全正确,因为添加/更改转换需要修改层次结构的根(破坏一切)。
  • 这是一个寻找问题的模式,而不是寻找解决方案的问题(有模式)。你试图理解这些模式很好,但我认为这种情况会让你头疼。您可以一次使用一种模式来学习它们(状态可以在这种情况下工作,但我认为这不是一个很好的模式,因为如果您的状态机发生变化,它就太脆弱了——有更灵活的方式来编写状态机器)。

标签: java design-patterns solid-principles open-closed-principle


【解决方案1】:

注意: 从 OP 来看,尚不清楚它是数字视频播放器,会根据当前模式(播放或录制)自动更改其 UI,还是老式视频带键的播放器(这意味着用户可以在播放模式时点击记录)。

所以,这只是一个可以帮助您前进的想法。

VideoPlayer 界面允许用户开始播放或录制。 When one of these is chosen, the user is handed over a different interface (a contract) that specifies what actions are possible.

public interface VideoPlayer {
    PlayerContext play();
    RecorderContext record();
}

public class PlayerContext {
    private VideoPlayer videoPlayer;
    private PlayerState playerState;

    public PlayerContext(VideoPlayer videoPlayer) {
        this.videoPlayer = videoPlayer;
        //this.playerState = ..init with PlayingState..
    }

    PlayerContext play() {
        playerState.play();
        return this;
    }
    PlayerContext pause() {
        playerState.pause();
        return this;
    }
    VideoPlayer stop() {
        playerState.stop();
        return videoPlayer;
    }
    PlayerContext forward() {
        playerState.forward();
        return this;
    }
    PlayerContext backward() {
        playerState.backward();
        return this;
    }
   //Methods to enable state switching
}


public class RecorderContext {
    private VideoPlayer videoPlayer;
    private RecorderState recorderState;

    public RecorderContext(VideoPlayer videoPlayer) {
        this.videoPlayer = videoPlayer;
        //this.recorderState = ..init with record state
    }

    RecorderContext pause() {
        recorderState.pause();
        return this;
    }
    RecorderContext record() {
        recorderState.record();
        return this;
    }
    VideoPlayer stop() {
        recorderState.stop();
        return videoPlayer;
    }
   //Methods to enable state switching
}

当点击stop 时,用户可以返回并选择两个可用选项之一 - 即可以播放或录制。这就是stop 返回基类VideoPlayer 对象的原因。

public class ConcreteVideoPlayer implements VideoPlayer {

    @Override
    public PlayerContext play() {
        return new PlayerContext(this);
    }

    @Override
    public RecorderContext record() {
        return new RecorderContext(this);
    }
}
public interface PlayerState {
    void play();
    void pause();
    VideoPlayer stop();
    void forward();
    void backward();
}
public interface RecorderState {
    void pause();
    void record();
    VideoPlayer stop();
}

您可以自己实现每个状态实现(PlayerStateRecorderState)。

用法:

VideoPlayer videoPlayer = new ConcreteVideoPlayer();
PlayerContext playerContext = videoPlayer.play();
videoPlayer = playerContext.pause()
        .backward()
        .pause()
        .play() //.play() -> Invalid state calls have to be handled by the individual state implementations
        .stop();
RecorderContext recordContext = videoPlayer.record();
videoPlayer = recordContext.pause()
        .record()
        .pause()
        .record()
        .stop();

我希望这会有所帮助!

【讨论】:

  • 老实说仍然很困惑,这与我的实现有很大不同
  • 它确实有帮助,但我再次改变了一些实现
猜你喜欢
  • 2013-08-09
  • 2011-09-04
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 2019-03-03
  • 1970-01-01
  • 2011-04-22
相关资源
最近更新 更多