状态模式
简介
相同的操作对于不同状态产生不同的作用。
类图
代码
-
设计一个手机类假设按下音量减小键,此时手机有三个状态会产生不同的反应 open(打开状态此时处于亮屏按下向下键音量减小),close(此时处于关闭状态,按下手机亮屏),document(此时处于阅读文档状态按下向下翻页)
public class Phone { String state; public void downKey() { if(state.equals("close")) { System.out.println("手机亮屏"); } else if(state.equals("open")) { System.out.println("音量变小"); } else if(state.equals("document")) { System.out.println("文档向下翻页"); } } }
-
问题:存在非常多的判断,代码的可阅读性和维护性非常差
- 解决:采用状态模式为手机定义不同的状态类进行相关操作后修改状态类
// 手机 public class MyPhone { private State state = new CloseState(this); void downKey() { state.downKey(); } void changeState(State state) { this.state = state; } } // 状态抽象类,为所有状态的父类 public abstract class State { MyPhone myPhone; public State(MyPhone myPhone) { this.myPhone = myPhone; } abstract void downKey(); } // 以下为所有不同状态 public class CloseState extends State{ public CloseState(MyPhone myPhone) { super(myPhone); } public void downKey() { System.out.println("此时处于息屏状态,手机亮屏,修改状态"); this.myPhone.changeState(new OpenState(myPhone)); } } public class DocumentState extends State{ public DocumentState(MyPhone myPhone) { super(myPhone); } public void downKey() { System.out.println("此时处于阅读文档状态,向下翻页"); } } public class OpenState extends State{ public OpenState(MyPhone myPhone) { super(myPhone); } public void downKey() { System.out.println("此时处于亮屏状态,音量减小"); } } // 客户端 public class Client { public static void main(String[] args) { MyPhone myPhone = new MyPhone(); // 初始状态为关闭状态,此时按下后为打开状态 myPhone.downKey(); // 此时为打开状态,按下后减小音量 myPhone.downKey(); // 此时切换成阅读文档 myPhone.changeState(new DocumentState(myPhone)); myPhone.downKey(); } } /* 输出: 此时处于息屏状态,手机亮屏,修改状态 此时处于亮屏状态,音量减小 此时处于阅读文档状态,向下翻页 */
与其他设计模式比较
可以发现与策略模式非常相似,但是不同的是状态模式中几个状态是知道彼此存在的,而策略模式不同策略无关系。