Java: State Pattern
/**
* 版权所有 2022 涂聚文有限公司
* 许可信息查看:
* 描述:
* 状态模式 State Pattern
* 历史版本: JDK 14.02
* 2022-09-12 创建者 geovindu
* 2022-09-12 添加 Lambda
* 2022-09-12 修改:date
* 接口类
* 2022-09-12 修改者:Geovin Du
* 生成API帮助文档的指令:
* javadoc - -encoding Utf-8 -d apidoc Player.java
* Interface
* Record
* Annotation
* Enum
*from: https://refactoringguru.cn/design-patterns/state/java/example#example-0--ui-Player-java
* */
package com.javapatterns.state.UI;
import java.util.ArrayList;
import java.util.List;
import com.javapatterns.state.states.*;
/**
*
*
* */
public class Player {
private State state;
private boolean playing = false;
private List<String> playlist = new ArrayList<>();
private int currentTrack = 0;
/**
*
*
* */
public Player() {
this.state = new ReadyState(this);
setPlaying(true);
for (int i = 1; i <= 12; i++) {
playlist.add("Track " + i);
}
}
/**
*
*
* */
public void changeState(State state) {
this.state = state;
}
/**
*
*
* */
public State getState() {
return state;
}
/**
*
*
* */
public void setPlaying(boolean playing) {
this.playing = playing;
}
/**
*
*
* */
public boolean isPlaying() {
return playing;
}
/**
*
*
* */
public String startPlayback() {
return "Playing " + playlist.get(currentTrack);
}
/**
*
*
* */
public String nextTrack() {
currentTrack++;
if (currentTrack > playlist.size() - 1) {
currentTrack = 0;
}
return "Playing " + playlist.get(currentTrack);
}
/**
*
*
* */
public String previousTrack() {
currentTrack--;
if (currentTrack < 0) {
currentTrack = playlist.size() - 1;
}
return "Playing " + playlist.get(currentTrack);
}
/**
*
*
* */
public void setCurrentTrackAfterStop() {
this.currentTrack = 0;
}
}
/**
* 版权所有 2022 涂聚文有限公司
* 许可信息查看:
* 描述:
* 状态模式 State Pattern
* 历史版本: JDK 14.02
* 2022-09-12 创建者 geovindu
* 2022-09-12 添加 Lambda
* 2022-09-12 修改:date
* 接口类
* 2022-09-12 修改者:Geovin Du
* 生成API帮助文档的指令:
* javadoc - -encoding Utf-8 -d apidoc UI.java
* Interface
* Record
* Annotation
* Enum
*
* */
package com.javapatterns.state.UI;
import javax.swing.*;
import java.awt.*;
import com.javapatterns.state.states.*;
/**
*
*
* */
public class UI {
private Player player;
private static JTextField textField = new JTextField();
/**
*
*
* */
public UI(Player player) {
this.player = player;
}
/**
*
*
* */
public void init() {
JFrame frame = new JFrame("Test player");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel context = new JPanel();
context.setLayout(new BoxLayout(context, BoxLayout.Y_AXIS));
frame.getContentPane().add(context);
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER));
context.add(textField);
context.add(buttons);
// Context delegates handling user's input to a state object. Naturally,
// the outcome will depend on what state is currently active, since all
// states can handle the input differently.
JButton play = new JButton("Play");
play.addActionListener(e -> textField.setText(player.getState().onPlay()));
JButton stop = new JButton("Stop");
stop.addActionListener(e -> textField.setText(player.getState().onLock()));
JButton next = new JButton("Next");
next.addActionListener(e -> textField.setText(player.getState().onNext()));
JButton prev = new JButton("Prev");
prev.addActionListener(e -> textField.setText(player.getState().onPrevious()));
frame.setVisible(true);
frame.setSize(300, 100);
buttons.add(play);
buttons.add(stop);
buttons.add(next);
buttons.add(prev);
}
}
/**
* 版权所有 2022 涂聚文有限公司
* 许可信息查看:
* 描述:
* 状态模式 State Pattern
* 历史版本: JDK 14.02
* 2022-09-12 创建者 geovindu
* 2022-09-12 添加 Lambda
* 2022-09-12 修改:date
* 接口类
* 2022-09-12 修改者:Geovin Du
* 生成API帮助文档的指令:
* javadoc - -encoding Utf-8 -d apidoc State.java
* Interface
* Record
* Annotation
* Enum
*
* */
package com.javapatterns.state.states;
import com.javapatterns.state.UI.*;
/**
* Common interface for all states.
*/
public abstract class State {
Player player;
/**
* Context passes itself through the state constructor. This may help a
* state to fetch some useful context data if needed.
*/
State(Player player) {
this.player = player;
}
/**
*
*
* */
public abstract String onLock();
/**
*
*
* */
public abstract String onPlay();
/**
*
*
* */
public abstract String onNext();
/**
*
*
* */
public abstract String onPrevious();
}
/**
* 版权所有 2022 涂聚文有限公司
* 许可信息查看:
* 描述:
* 状态模式 State Pattern
* 历史版本: JDK 14.02
* 2022-09-12 创建者 geovindu
* 2022-09-12 添加 Lambda
* 2022-09-12 修改:date
* 接口类
* 2022-09-12 修改者:Geovin Du
* 生成API帮助文档的指令:
* javadoc - -encoding Utf-8 -d apidoc LockedState.java
* Interface
* Record
* Annotation
* Enum
*
* */
package com.javapatterns.state.states;
import com.javapatterns.state.UI.*;
/**
* Concrete states provide the special implementation for all interface methods.
*/
public class LockedState extends State {
/**
*
*
* */
LockedState(Player player) {
super(player);
player.setPlaying(false);
}
/**
*
*
* */
@Override
public String onLock() {
if (player.isPlaying()) {
player.changeState(new ReadyState(player));
return "Stop playing";
} else {
return "Locked...";
}
}
/**
*
*
* */
@Override
public String onPlay() {
player.changeState(new ReadyState(player));
return "Ready";
}
/**
*
*
* */
@Override
public String onNext() {
return "Locked...";
}
/**
*
*
* */
@Override
public String onPrevious() {
return "Locked...";
}
}
/**
* 版权所有 2022 涂聚文有限公司
* 许可信息查看:
* 描述:
* 状态模式 State Pattern
* 历史版本: JDK 14.02
* 2022-09-12 创建者 geovindu
* 2022-09-12 添加 Lambda
* 2022-09-12 修改:date
* 接口类
* 2022-09-12 修改者:Geovin Du
* 生成API帮助文档的指令:
* javadoc - -encoding Utf-8 -d apidoc ReadyState.java
* Interface
* Record
* Annotation
* Enum
*
* */
package com.javapatterns.state.states;
import com.javapatterns.state.UI.*;
/**
* They can also trigger state transitions in the context.
*/
public class ReadyState extends State {
/**
*
*
* */
public ReadyState(Player player) {
super(player);
}
/**
*
*
* */
@Override
public String onLock() {
player.changeState(new LockedState(player));
return "Locked...";
}
/**
*
*
* */
@Override
public String onPlay() {
String action = player.startPlayback();
player.changeState(new PlayingState(player));
return action;
}
/**
*
*
* */
@Override
public String onNext() {
return "Locked...";
}
/**
*
*
* */
@Override
public String onPrevious() {
return "Locked...";
}
}
/**
* 版权所有 2022 涂聚文有限公司
* 许可信息查看:
* 描述:
* 状态模式 State Pattern
* 历史版本: JDK 14.02
* 2022-09-12 创建者 geovindu
* 2022-09-12 添加 Lambda
* 2022-09-12 修改:date
* 接口类
* 2022-09-12 修改者:Geovin Du
* 生成API帮助文档的指令:
* javadoc - -encoding Utf-8 -d apidoc PlayingState.java
* Interface
* Record
* Annotation
* Enum
*
* */
package com.javapatterns.state.states;
import com.javapatterns.state.UI.*;
/**
*
*
* */
public class PlayingState extends State {
/**
*
*
* */
PlayingState(Player player) {
super(player);
}
/**
*
*
* */
@Override
public String onLock() {
player.changeState(new LockedState(player));
player.setCurrentTrackAfterStop();
return "Stop playing";
}
/**
*
*
* */
@Override
public String onPlay() {
player.changeState(new ReadyState(player));
return "Paused...";
}
/**
*
*
* */
@Override
public String onNext() {
return player.nextTrack();
}
/**
*
*
* */
@Override
public String onPrevious() {
return player.previousTrack();
}
}
调用:
// 状诚模式
com.javapatterns.state.UI.Player player = new com.javapatterns.state.UI.Player();
UI ui = new UI(player);
ui.init();
输出:

哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号