Java 设计模式之状态模式
概述
- 状态模式(State):当一个对象的内部状态改变时允许改变其行为,这个对象看起来像是改变了其类。
- 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化
状态模式与策略模式区别:
- 状态模式中类有状态,状态的修改会改变整个类行为。
- 策略模式没有状态,策略的选择由客户端决定。
UML图
- Context:上下文环境类,负责状态的切换。
- State:抽象状态类,定义状态的行为。
- ConcreteState:具体状态类,实现具体的状态行为。
传统模式
public class MusicController {
private static final int POWER_ON = 1;
private static final int POWER_OFF = 2;
private int state = POWER_OFF;
public void powerOn() {
state = POWER_ON;
System.out.println("开机");
}
public void powerOff() {
state = POWER_OFF;
System.out.println("关机");
}
public void prevSong() {
if (state == POWER_ON) {
System.out.println("上一首");
}
}
public void nextSong() {
if (state == POWER_ON) {
System.out.println("下一首");
}
}
}
使用:
public class Client {
public static void main(String[] args) {
MusicController controller = new MusicController();
controller.powerOn();
controller.nextSong();
controller.prevSong();
controller.powerOff();
controller.nextSong();
}
}
输出:
开机
下一首
上一首
关机
状态模式优化
定义抽象状态类:
public interface PowerState {
void prevSong();
void nextSong();
}
定义具体状态累:
public class PowerOnState implements PowerState {
@Override
public void prevSong() {
System.out.println("上一首");
}
@Override
public void nextSong() {
System.out.println("下一首");
}
}
public class PowerOffState implements PowerState {
@Override
public void prevSong() {
System.out.println("请先开机");
}
@Override
public void nextSong() {
System.out.println("请先开机");
}
}
定义上下文环境类:
public class MusicContext {
private PowerState offState;
private PowerState onState;
private PowerState currentState;
public MusicContext() {
offState = new PowerOffState();
onState = new PowerOnState();
}
public void setMusicState(PowerState musicState) {
this.currentState = musicState;
}
public void powerOn() {
setMusicState(onState);
System.out.println("开机");
}
public void powerOff() {
setMusicState(offState);
System.out.println("关机");
}
public void nextSong() {
currentState.nextSong();
}
public void prevSong() {
currentState.prevSong();
}
}
使用:
public class Client {
public static void main(String[] args) {
MusicContext context = new MusicContext();
context.powerOn();
context.nextSong();
context.prevSong();
context.powerOff();
context.prevSong();
}
}
输出:
下一首
上一首
关机
请先开机