状态模式
定义摘自《head first》中:
状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
对于使用者来说看起来好像是能够修改自己的类,实际上是委托状态对象来改变相关操作。
状态模式类图如下(截图于《head first》):
对于状态模式,我自己举了例子:描述一个人经过外界时间的影响,心情状态会有不同的变化。
例如:一个人捡到钱了,当然是很高兴,钱丢了当然就不高兴也就是悲伤了,当丢的钱又捡回来了,于是就从悲伤变成高兴了。
看下面状态图:
使用状态模式实现,代码如下:
1.状态接口
/** * 状态接口 * * @author ChenST * * @create 2010-3-25 */ public abstract class State { /** 状态名 */ private String name; /** * 捡到钱了 */ public abstract void pickMoney(); /** * 丢钱了 */ public abstract void loseMoney(); /** * 钱捡回来了 */ public abstract void backMoney(); public String getName() { return name; } public void setName(String name) { this.name = name; } }
2.正常状态
/** * 正常状态 * * @author Administrator * * @create 2010-3-25 */ public class NormalState extends State { /** 该状态所发生的实体 */ private Person person; public NormalState(Person person) { this.person=person; this.setName("正常"); } public void loseMoney() { //丢钱了,很悲伤,状态转变 System.out.println("钱丢啦!"); person.setCurrent(person.getSad()); } public void pickMoney() { System.out.println("捡到钱了!"); person.setCurrent(person.getHappy()); } public void backMoney() { //无状态改变 } }
3.高兴状态
/** * 高兴的状态 * * @author ChenST * * @create 2010-3-25 */ public class HappyState extends State { /** 该状态所发生的实体 */ private Person person; public HappyState(Person person) { this.person=person; this.setName("高兴"); } public void backMoney() { //无任何状态改变 } public void loseMoney() { //无任何状态改变 } public void pickMoney() { //无任何状态改变 } }
4.悲伤状态
/** * 悲伤状态 * * @author ChenST * * @create 2010-3-25 */ public class SadState extends State { /** 该状态所发生的实体 */ private Person person; public SadState(Person person) { this.person=person; this.setName("悲伤"); } public void backMoney() { //丢失的钱失而复得,很高兴 System.out.println("捡回来了,原来丢在这儿了"); person.setCurrent(person.getHappy()); } public void loseMoney() { //无状态改变 } public void pickMoney() { //无状态改变 } }
5.人类,状态存在的实体
/** * 一个人的类 * * @author ChenST * * @create 2010-3-25 */ public class Person extends State{ /** 高兴的状态 */ private State happy; /** 悲伤的状态 */ private State sad; /** 正常的状态 */ private State normal; /** 当前的状态 */ private State current; public Person(){ this.happy=new HappyState(this); this.sad=new SadState(this); this.normal=new NormalState(this); //当前状态为正常状态 this.current=this.normal; } /** * 显示打印当前状态 */ public void showCurrentState(){ System.out.println(current.getName()); } /** * 重新设置状态,回复默认状态 */ public void resetState(){ this.current=this.normal; } // //委托给状态对象去执行操作 // public void backMoney() { current.backMoney(); } public void loseMoney() { current.loseMoney(); } public void pickMoney() { current.pickMoney(); } public State getCurrent() { return current; } public void setCurrent(State current) { this.current = current; } public State getHappy() { return happy; } public void setHappy(State happy) { this.happy = happy; } public State getNormal() { return normal; } public void setNormal(State normal) { this.normal = normal; } public State getSad() { return sad; } public void setSad(State sad) { this.sad = sad; } }
6.测试类
/** * 测试类 * * @author ChenST * * @create 2010-3-25 */ public class Test { public static void main(String[] args) { //今天詹姆斯出去买东西 Person james=new Person(); james.pickMoney(); //今天运气好,捡到钱了 james.showCurrentState();//查看下詹姆斯的心情 james.resetState(); //于是不买东西了回家了.(恢复默认状态) james.showCurrentState();//查看下詹姆斯的心情 //第二天詹姆斯又出去买东西 james.loseMoney(); //今天运气不好,丢钱了 james.showCurrentState();//查看下詹姆斯的心情 james.backMoney(); //今天运气还不算很差,钱捡回来了。 james.showCurrentState();//查看下詹姆斯的心情 } }
7.运行结果
捡到钱了! 高兴 正常 钱丢啦! 悲伤 捡回来了,原来丢在这儿了 高兴
OK~~完毕~可以看到,如果对状态的增加或者修改,或者对行为的增加或修改,都可以很好的扩展和维护。只要在人的类里面增加相应的状态和方法即可改变,而不需要改变整体结构,用增加类来代替if 的条件判断。