简介
对象的行为依赖于它的状态(属性),可以根据状态的改变而改变相关行为。
UML图:
应用场景:
- 对象的行为取决于其状态,并且必须要在运行时刻根据状态而改变行为
- 代码中包含大量与对象状态有关的条件语句
示例
上午、下午、晚上工作的状态
- 上下文对象:
public class Work {
/**
* 工作状态
*/
private State state;
/**
* 当前时间
*/
private int hour;
/**
* 工作是否完成
*/
private boolean isFinished;
public Work() {
// 初始化操作
this.state = new MorningState();
}
public void writeProgram() {
state.writeProgram(this);
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public boolean isFinished() {
return isFinished;
}
public void setFinished(boolean finished) {
isFinished = finished;
}
}
- 状态
public interface State {
void writeProgram(Work work);
}
public class MorningState implements State {
@Override
public void writeProgram(Work work) {
if (work.getHour() < 12) {
System.out.println("当前时间:" + work.getHour() + ",干劲十足!");
} else {
work.setState(new NoonState());
work.writeProgram();
}
}
}
public class NoonState implements State {
@Override
public void writeProgram(Work work) {
if (work.getHour() < 13) {
System.out.println("当前时间:" + work.getHour() + ",好饿,开始干饭!");
} else {
work.setState(new AfternoonState());
work.writeProgram();
}
}
}
public class AfternoonState implements State {
@Override
public void writeProgram(Work work) {
if (work.getHour() < 18) {
System.out.println("当前时间:" + work.getHour() + ",开始上班,有点疲惫!");
} else {
work.setState(new EveningState());
work.writeProgram();
}
}
}
public class EveningState implements State {
@Override
public void writeProgram(Work work) {
if (!work.isFinished()) {
System.out.println("当前时间:" + work.getHour() + ",又要加班");
} else {
System.out.println("当前时间:" + work.getHour() + ",下班啦!");
}
}
}
- 运行
public class Main {
public static void main(String[] args) {
Work work = new Work();
// 上午
work.setHour(9);
work.writeProgram();
// 中午
work.setHour(12);
work.writeProgram();
// 下午
work.setHour(16);
work.writeProgram();
// 晚上
work.setHour(18);
// work.setFinished(true);
work.writeProgram();
}
}
总结
- 优点
- 只需改变对象的状态,就可改变对象的行为
- 多个环境对象共享一个状态对象,可以减少系统中对象的个数
- 缺点
- 增加系统类和对象的个数
- 使用不当将造成程序结构和代码的混乱
- 不符合开闭原则,新增状态需要修改源码
VS 策略模式
- 状态模式重在各个状态之间的切换从而有不同的行为,策略模式重在根据具体情况选择策略不涉及状态的切换
- 状态模式不同状态做不同的事情且不能相互替换,策略模式解决的都是同一件事