状态模式
State模式也叫状态模式,是行为设计模式的一种。State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。
一、结构与角色
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况,例如下面判断hour。把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。
- Context:用户对象,拥有一个State类型的成员,以标识对象的当前状态
- State:接口或基类封装与Context的特定状态相关的行为
- ConcreteState:接口实现类或子类实现了一个与Context某个状态相关的行为
二、没有使用状态模式
2.1 Person
考逻辑判断语句去改变状态的行为
public class Person {
private int hour;
public void doSomething(){
if(hour == 7){
System.out.println("get up");
}else if(hour == 12){
System.out.println("eat lunch");
}else if(hour == 18){
System.out.println("eat dinner");
}else{
System.out.println("study");
}
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
}
2.2 MainClass
public class MainClass {
public static void main(String[] args){
//改变对象的内部状态而改变对象的行为
Person person = new Person();
person.setHour(7);
person.doSomething();
person.setHour(18);
person.doSomething();
}
}
三、使用状态模式改造代码
3.1 State
public abstract class State {
public abstract void doSomething(Person person);
}
3.2 MState
public class MState extends State {
public void doSomething(Person person) {
if (person.getHour() == 7) {
System.out.println("吃早餐");
}else{
person.setState(new LState());
person.doSomething();
}
}
}
3.3 LState
public class LState extends State {
public void doSomething(Person person) {
if(person.getHour()==12) {
System.out.println("吃午餐");
}else{
person.setState(new NState());
person.doSomething();
}
}
}
3.4 NState
public class NState extends State {
public void doSomething(Person person) {
if(person.getHour()==18) {
System.out.println("吃晚饭");
}else{
person.setState(new OState());
person.doSomething();
}
}
}
3.5 OState
public class OState extends State {
public void doSomething(Person person) {
System.out.println("学习");
}
}
3.6 Person
public class Person {
private int hour;
private State state;
public Person(){
//初始化最早的状态判断
state = new MState();
}
public void doSomething(){
state.doSomething(this);
//复位
state = new MState();
}
... omit setter and getter
}
3.7 MainClass
public class MainClass {
public static void main(String[] args){
Person person = new Person();
person.setHour(7);
person.doSomething();
person.setHour(18);
person.doSomething();
person.setHour(7);
person.doSomething();
}
}