浏览 1078 次
锁定老帖子 主题:圣斗士星矢的状态模式和观察者模式
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-15
星矢:动画片《圣斗士星矢》的男猪脚,超级小强,怎么打也打不死。 雅典娜:动画片《圣斗士星矢》的女猪脚,自称女神,手下有88个男人为他卖命。 状态模式:为了方便的控制状态的变化,避免一堆IF/ELSE,以及状态规则改变的时避免代码改动的混乱。 观察者模式:一个被观察者一动,多个观察者跟着动,经常用于界面UI。 话说星矢和很强的某斗士甲对打,雅典娜在一边看,星矢总是挨揍,每次挨揍完之后星矢的状态总是会发生一些变化: 正常--挨打--瀕死--挨打--小宇宙爆发--挨打--瀕死--挨打--女神护体--挨打(星矢无敌了,打也没用,战斗结束)--正常 以上状态转变用状态模式来表现,一个Saiya类代表星矢,一个SaiyaState代表他的状态,SaiyaState下面有多个子类,分别代表星矢的多种状态,如正常NORMAL、瀕死DYING、小宇宙爆发UNIVERSE、女神护体GODDESS,即把状态抽象成对象,在每种状态里面实现被打的时候所需要更改的状态,这样就避免了每次被打都要进行一次IF/ELSE的判断。 Java代码 public class Saiya extends Observable { //定义星矢的四种状态 public final SaiyaState NORMAL = new NormalState(this); public final SaiyaState DYING = new DyingState(this); public final SaiyaState GODDESS = new GoddessState(this); public final SaiyaState UNIVERSE = new UniverseState(this); private SaiyaState state=NORMAL; private SaiyaState laststate=null; public void hit(){ //调用当前状态的被打方法 反过来改变自己的状态 state.hit(); } public String status(){ //当前状态名 return state.status(); } protected void setState(SaiyaState state){ laststate=this.state; this.state=state; //观察者模式 setChanged(); notifyObservers("星矢状态变化"); } public String getlastStatus(){ return laststate.status(); } public class Saiya extends Observable { //定义星矢的四种状态 public final SaiyaState NORMAL = new NormalState(this); public final SaiyaState DYING = new DyingState(this); public final SaiyaState GODDESS = new GoddessState(this); public final SaiyaState UNIVERSE = new UniverseState(this); private SaiyaState state=NORMAL; private SaiyaState laststate=null; public void hit(){ //调用当前状态的被打方法 反过来改变自己的状态 state.hit(); } public String status(){ //当前状态名 return state.status(); } protected void setState(SaiyaState state){ laststate=this.state; this.state=state; //观察者模式 setChanged(); notifyObservers("星矢状态变化"); } public String getlastStatus(){ return laststate.status(); } 星矢的状态 Java代码 public abstract class SaiyaState { protected Saiya saiya; public SaiyaState(Saiya saiya) { this.saiya = saiya; } public String status(){ String name=getClass().getName(); return name.substring(name.lastIndexOf(".")+1); } //星矢被打了 public abstract void hit(); } public abstract class SaiyaState { protected Saiya saiya; public SaiyaState(Saiya saiya) { this.saiya = saiya; } public String status(){ String name=getClass().getName(); return name.substring(name.lastIndexOf(".")+1); } //星矢被打了 public abstract void hit(); } 在每种状态里面实现被打的时候所需要更改的状态,例如小宇宙爆发状态下被打 Java代码 public class UniverseState extends SaiyaState { /** * @param saiya */ public UniverseState(Saiya saiya) { super(saiya); } /* 小宇宙爆发状态被打进入瀕死状态 * */ public void hit() { saiya.setState( saiya.DYING); } } public class UniverseState extends SaiyaState { /** * @param saiya */ public UniverseState(Saiya saiya) { super(saiya); } /* 小宇宙爆发状态被打进入瀕死状态 * */ public void hit() { saiya.setState( saiya.DYING); } } 雅典娜在一边看,星矢每次被打她都要给星矢加油,她是个观察者,星矢是被观察者,这里星矢实现java.util.Observable,每次被打hit就notifyObservers,雅典娜就加油。 Java代码 public class Athena implements Observer { /* 我是雅典娜 我是观察者 * */ public void update(Observable arg0, Object arg1) { System.out.println("雅典娜说:星矢加油啊!!!"); } } public class Athena implements Observer { /* 我是雅典娜 我是观察者 * */ public void update(Observable arg0, Object arg1) { System.out.println("雅典娜说:星矢加油啊!!!"); } } 总的来看 这个过程就是这样子: Java代码 public class StateMain { public static void main(String[] args) { Saiya saiya = new Saiya(); Observer athena = new Athena(); saiya.addObserver(athena); System.out.println("星矢最初的状态是:" + saiya.status()); for (int i = 0; i < 5; i++) { System.out.println("星矢被揍了" + (i + 1) + "次"); saiya.hit(); System.out.println("星矢现在的状态是:" + saiya.status()); } } } public class StateMain { public static void main(String[] args) { Saiya saiya = new Saiya(); Observer athena = new Athena(); saiya.addObserver(athena); System.out.println("星矢最初的状态是:" + saiya.status()); for (int i = 0; i < 5; i++) { System.out.println("星矢被揍了" + (i + 1) + "次"); saiya.hit(); System.out.println("星矢现在的状态是:" + saiya.status()); } } } 结果星矢在雅典娜的帮助下,有惊无险的战胜了很强的某斗士甲: Java代码 星矢最初的状态是:NormalState 星矢被揍了1次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:DyingState 星矢被揍了2次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:UniverseState 星矢被揍了3次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:DyingState 星矢被揍了4次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:GoddessState 星矢被揍了5次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:NormalState 星矢最初的状态是:NormalState 星矢被揍了1次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:DyingState 星矢被揍了2次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:UniverseState 星矢被揍了3次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:DyingState 星矢被揍了4次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:GoddessState 星矢被揍了5次 雅典娜说:星矢加油啊!!! 星矢现在的状态是:NormalState 总结:状态模式的缺点就是会弄出很多子类,如果状态没那么复杂,状态规则改变的可能性比较小的话就不要用了 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |