设计模式之状态模式
2017-06-26 14:09
302 查看
设计模式之状态模式
状态模式简介
有时候,会遇到这样的情形,某一个对象,有多种不同的状态,在不同的状态下,可能有不同的行为。要实现这样一种服务,可以使用最简单的if.else结构,但是呢,这种方式在状态比较多的时候就会使得代码变得比较冗长,每次有新的状态的时候,都需要修改该处代码,而且,在后期进行维护的时候,也不便于理解;还有另一一种方式,就是状态模式,所谓的状态模式,通俗地来讲,就是把对象的所有状态进行封装,将每一个状态独立抽取出来,形成一个状态类,这样,当需要增加新的状态的时候,就不需要更改原有的代码了。状态模式的具体实现
这里来简单模拟一个号码卡的三种状态(正常状态,欠费状态,停机状态)变化来更加深入的了解状态模式。当余额大于0的时候处于正常状态,当余额小于0但是大于-50的时候,处于欠费状态,此时依旧可以打电话,当欠费超过50的时候,处于停止状态,此时打电话功能将被限制
首先是没有使用状态模式的情景,也就是通过冗长的if.else语句结构来实现这样一个过程
/** * Created by Huanfeng.Xu on 2017-06-26. */ public class Original { public Original(double money){ this.money = money; state = NORMAL; } private double money; private String state; private final static String STOP = "stop"; private final static String NORMAL = "normal"; private final static String OWNED = "owned"; public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } // 调用具体的业务方法的时候任然需要进行状态的校验,根据不同的状态采取不同的行为 public void call(){ check(); if (STOP.equals(state)){ System.out.println("当前账号处于停机状态,不允许打电话也不允许接听电话"); }else{ if (OWNED.equals(state)){ System.out.println("当前账号处于欠费状态,请注意, 欠费金额 " + money); }else if (NORMAL.equals(state)){ System.out.println("打电话中..."); } money -= 10; } } // 查看当前系统的状态 public void check(){ if (money < -50){ state = STOP; }else if (money < 0 && money >= -50){ state = OWNED; }else if (money >= 0){ state = NORMAL; } } public void charge(double money){ this.money += money; System.out.println("充值费用 " + money); check(); } }
从上面的代码中可以看到,每次执行一个业务方法的时候,都需要检查此时系统所处的状态,然后再根据不同的业务方法,判断不同状态下应该有的行为,当业务方法比较多的时候,整个的代码就会变得相对冗余了,而且修改起来几乎每一个业务方法都需要进行修改
接下来来看下使用状态模式之后的情况
/** * Created by Huanfeng.Xu on 2017-06-26. */ public class Account { private double money; private State state; // 省略set/get方法 public void call(){ state.call(); } public void charge(double money){ state.charge(money); } } // 抽象的状态类 abstract class State{ protected Account account; public abstract void checkState(); public void charge(double money){ account.setMoney(account.getMoney() + money); System.out.println("充值费用 " + money); checkState(); } public abstract void call(); } //正常状态类 class Normal extends State{ public Normal(Account account){ this.account = account; } @Override public void checkState() { double currentMoney = account.getMoney(); if (currentMoney < 0 && currentMoney >= -50 ){ System.out.println("当前账号余额不足,已经处于欠费状态,欠费 " + account.getMoney()); account.setState(new Owned(account)); }else if (currentMoney < -50){ System.out.println("欠费过多,账号已经停机"); account.setState(new Stopped(account)); } } @Override public void call() { account.setMoney(account.getMoney() - 10); System.out.println("打电话中..."); checkState(); } } //欠费状态类 class Owned extends State{ public Owned(Account account){ this.account = account; } @Override public void checkState() { double currentMoney = account.getMoney(); if (currentMoney > 0){ account.setState(new Normal(account)); }else if (currentMoney < -50){ account.setState(new Stopped(account)); } } @Override public void call() { System.out.println("当前账号处于欠费状态,请注意, 欠费金额 " + account.getMoney()); account.setMoney(account.getMoney() - 10); checkState(); } } // 停机状态类 class Stopped extends State{ public Stopped(Account account){ this.account = account; } @Override public void checkState() { double currentMoney = account.getMoney(); if (currentMoney > 0){ System.out.println("账号已经恢复正常"); account.setState(new Normal(account)); } } @Override public void call() { System.out.println("当前账号处于停机状态,不允许打电话也不允许接听电话"); } }
可以看到,此时将状态的变化交给了状态类本身,不用的状态类根据当前的行为,操作之后自动切换到不同的状态,此时就不再需要进行状态的检测了,账号类(环境类)所拥有的状态就是当前的状态了。并且把不同的状态的行为封装起来,此时,不同的状态类只需要负责自己的行为判断即可。当需要修改的时候,所需要修改的也仅仅是对应的状态类的行为了,而再是对每一个的业务方法都进行修改。
总结
状态模式,主要的思想就是把不同的状态及其行为抽取出来,封装成对应的状态对象,可以理解是将原本比较庞大的if.else语句抽取出来,分散到各自对应的状态之中,使得之后的修改都是直接针对对象进行修改,增加代码的可维护性。相关文章推荐
- 设计模式笔记 21. State 状态模式(行为型模式)
- 设计模式--状态模式(State)
- [导入]C#面向对象设计模式纵横谈(22):(行为型模式) State 状态模式.zip(6.24 MB)
- .NET设计模式(21): 状态模式(State Pattern)
- 设计模式之state状态模式
- 设计模式之State Pattern 状态模式。
- 设计模式之状态模式
- 设计模式之State(状态)
- 设计模式初学者系列之状态模式
- 设计模式--状态模式(State)
- 设计模式与泡mm的关系之state状态模式及再思考
- 设计模式学习笔记(二十二)——State状态
- 设计模式——状态模式
- 设计模式 - State Pattern(状态模式)
- 设计模式(17)-状态模式(State)
- 交互设计与状态模式,兼谈几个失败的设计
- [★] .NET 偶尔连接的设计策略 -联机状态- 脱机模式- 数据同步
- 设计模式——状态模式(State)
- head first 设计模式学习随笔(11)----状态模式
- 设计模式(19)-状态模式(State)