星矢动画片《圣斗士星矢》的男猪脚超级小强怎么打也打不死 雅典娜动画片《圣斗士星矢》的女猪脚自称女神手下有个男人为他卖命 状态模式为了方便的控制状态的变化避免一堆IF/ELSE以及状态规则改变的时避免代码改动的混乱 观察者模式一个被观察者一动多个观察者跟着动经常用于界面UI 话说星矢和很强的某斗士甲对打雅典娜在一边看星矢总是挨揍每次挨揍完之后星矢的状态总是会发生一些变化 正常挨打濒死挨打小宇宙爆发挨打濒死挨打女神护体挨打(星矢无敌了打也没用战斗结束)正常 以上状态转变用状态模式来表现一个Saiya类代表星矢一个SaiyaState代表他的状态SaiyaState下面有多个子类分别代表星矢的多种状态如正常NORMAL濒死DYING小宇宙爆发UNIVERSE女神护体GODDESS即把状态抽象成对象在每种状态里面实现被打的时候所需要更改的状态这样就避免了每次被打都要进行一次IF/ELSE的判断 Java代码 publicclassSaiyaextendsObservable{ //定义星矢的四种状态 publicfinalSaiyaStateNORMAL=newNormalState(this); publicfinalSaiyaStateDYING=newDyingState(this); publicfinalSaiyaStateGODDESS=newGoddessState(this); publicfinalSaiyaStateUNIVERSE=newUniverseState(this); privateSaiyaStatestate=NORMAL; privateSaiyaStatelaststate=null; publicvoidhit(){ //调用当前状态的被打方法反过来改变自己的状态 statehit(); } publicStringstatus(){ //当前状态名 returnstatestatus(); } protectedvoidsetState(SaiyaStatestate){ laststate=thisstate; thisstate=state; //观察者模式 setChanged(); notifyObservers(星矢状态变化); } publicStringgetlastStatus(){ returnlaststatestatus(); } publicclassSaiyaextendsObservable{ //定义星矢的四种状态 publicfinalSaiyaStateNORMAL=newNormalState(this); publicfinalSaiyaStateDYING=newDyingState(this); publicfinalSaiyaStateGODDESS=newGoddessState(this); publicfinalSaiyaStateUNIVERSE=newUniverseState(this); privateSaiyaStatestate=NORMAL; privateSaiyaStatelaststate=null; publicvoidhit(){ //调用当前状态的被打方法反过来改变自己的状态 statehit(); } publicStringstatus(){ //当前状态名 returnstatestatus(); } protectedvoidsetState(SaiyaStatestate){ laststate=thisstate; thisstate=state; //观察者模式 setChanged(); notifyObservers(星矢状态变化); } publicStringgetlastStatus(){ returnlaststatestatus(); } 星矢的状态 Java代码 publicabstractclassSaiyaState{ protectedSaiyasaiya; publicSaiyaState(Saiyasaiya){ thissaiya=saiya; } publicStringstatus(){ Stringname=getClass()getName(); returnnamesubstring(namelastIndexOf()+); } //星矢被打了 publicabstractvoidhit(); } publicabstractclassSaiyaState{ protectedSaiyasaiya; publicSaiyaState(Saiyasaiya){ thissaiya=saiya; } publicStringstatus(){ Stringname=getClass()getName(); returnnamesubstring(namelastIndexOf()+); } //星矢被打了 publicabstractvoidhit(); } 在每种状态里面实现被打的时候所需要更改的状态例如小宇宙爆发状态下被打 Java代码 publicclassUniverseStateextendsSaiyaState{ /** *@paramsaiya */ publicUniverseState(Saiyasaiya){ super(saiya); } /*小宇宙爆发状态被打进入濒死状态 * */ publicvoidhit(){ saiyasetState(saiyaDYING); } } publicclassUniverseStateextendsSaiyaState{ /** *@paramsaiya */ publicUniverseState(Saiyasaiya){ super(saiya); } /*小宇宙爆发状态被打进入濒死状态 * */ publicvoidhit(){ saiyasetState(saiyaDYING); } } 雅典娜在一边看星矢每次被打她都要给星矢加油她是个观察者星矢是被观察者这里星矢实现javautilObservable每次被打hit就notifyObservers雅典娜就加油 Java代码 publicclassAthenaimplementsObserver{ /*我是雅典娜我是观察者 * */ publicvoidupdate(ObservableargObjectarg){ Systemoutprintln(雅典娜说星矢加油啊!!!); } } publicclassAthenaimplementsObserver{ /*我是雅典娜我是观察者 * */ publicvoidupdate(ObservableargObjectarg){ Systemoutprintln(雅典娜说星矢加油啊!!!); } } 总的来看 这个过程就是这样子 Java代码 publicclassStateMain{ publicstaticvoidmain(String[]args){ Saiyasaiya=newSaiya(); Observerathena=newAthena(); saiyaaddObserver(athena); Systemoutprintln(星矢最初的状态是+saiyastatus()); for(inti=;i<;i++){ Systemoutprintln(星矢被揍了+(i+)+次); saiyahit(); Systemoutprintln(星矢现在的状态是+saiyastatus()); } } } publicclassStateMain{ publicstaticvoidmain(String[]args){ Saiyasaiya=newSaiya(); Observerathena=newAthena(); saiyaaddObserver(athena); Systemoutprintln(星矢最初的状态是+saiyastatus()); for(inti=;i<;i++){ Systemoutprintln(星矢被揍了+(i+)+次); saiyahit(); Systemoutprintln(星矢现在的状态是+saiyastatus()); } } } 结果星矢在雅典娜的帮助下有惊无险的战胜了很强的某斗士甲 Java代码 星矢最初的状态是NormalState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是DyingState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是UniverseState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是DyingState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是GoddessState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是NormalState 星矢最初的状态是NormalState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是DyingState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是UniverseState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是DyingState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是GoddessState 星矢被揍了次 雅典娜说星矢加油啊!!! 星矢现在的状态是NormalState 总结状态模式的缺点就是会弄出很多子类如果状态没那么复杂状态规则改变的可能性比较小的话就不要用了 |