Mous Kamel
Mous Kamel

Reputation: 277

How to apply State pattern and strategy pattern together?

I need to implement in Java an application that plays and record videos.
The video player has two states, Playing mode and recording mode.
While on playing mode, we can Play, Pause,Stop, ForwardandBackward the video.
On the other hand, in recording mode we can do Record, PauseorStop.
Here is what I did so far:UMLbr> I'm a little stuck. I dunno if I should create a strategy for every action of each mode or if I can make it even more simple.
I was thinking of giving the PlayingModeVideoPlayer and RecordingModeVideoPlayer their specefic strategies(multiples ones) but I don't know how to implement it. thank you
Playing and Recording Modes are two independent things. I don't need to implement the transition between these two entities.

Upvotes: 2

Views: 1390

Answers (1)

Thiyagu
Thiyagu

Reputation: 17910

Note: From the OP, it is not clear whether it a digital video player, that automatically changes its UI based on the current mode (playing or recording) or it is an old-fashioned video player with keys (which would mean the user could click on record when playing mode).

So, this is just an idea that can help you move forward.

The VideoPlayer interface allows a user to either start playing or recording. 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
}

When clicking on stop the user can go back and choose one of the two available option - i.,e can play or record. That is why the stop returns the base VideoPlayer object.

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();
}

You can implement each of the state implementations (PlayerState and RecorderState) yourself.

Usage:

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();

I Hope this helps!!

Upvotes: 1

Related Questions