挺喜歡里面的挨打、小宇宙爆發情節,相信圣斗士的fans都會喜歡,特此轉載。
來源:http://www.javaeye.com/topic/212142
星矢:動畫片《圣斗士星矢》的男豬腳,超級小強,怎么打也打不死。
雅典娜:動畫片《圣斗士星矢》的女豬腳,自稱女神,手下有88個男人為他賣命。
狀態模式:為了方便的控制狀態的變化,避免一堆IF/ELSE,以及狀態規則改變的時避免代碼改動的混亂。
觀察者模式:一個被觀察者一動,多個觀察者跟著動,經常用于界面UI。
話說星矢和很強的某斗士甲對打,雅典娜在一邊看,星矢總是挨揍,每次挨揍完之后星矢的狀態總是會發生一些變化:
正常--挨打--瀕死--挨打--小宇宙爆發--挨打--瀕死--挨打--女神護體--挨打(星矢無敵了,打也沒用,戰斗結束)--正常
以上狀態轉變用狀態模式來表現,一個Saiya類代表星矢,一個SaiyaState代表他的狀態,SaiyaState下面有多個子類,分別代表星矢的多種狀態,如正常NORMAL、瀕死DYING、小宇宙爆發UNIVERSE、女神護體GODDESS,即把狀態抽象成對象,在每種狀態里面實現被打的時候所需要更改的狀態,這樣就避免了每次被打都要進行一次IF/ELSE的判斷。
- 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 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 class UniverseState extends SaiyaState {
- /**
- * @param saiya
- */
- public UniverseState(Saiya saiya) {
- super(saiya);
- }
- /* 小宇宙爆發狀態被打進入瀕死狀態
- *
- */
- public void hit() {
- saiya.setState( saiya.DYING);
- }
- }
雅典娜在一邊看,星矢每次被打她都要給星矢加油,她是個觀察者,星矢是被觀察者,這里星矢實現java.util.Observable,每次被打hit就notifyObservers,雅典娜就加油。
- public class Athena implements Observer {
- /* 我是雅典娜 我是觀察者
- *
- */
- public void update(Observable arg0, Object arg1) {
- System.out.println("雅典娜說:星矢加油啊!!!");
- }
- }
總的來看 這個過程就是這樣子:
- 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());
- }
- }
- }
結果星矢在雅典娜的幫助下,有驚無險的戰勝了很強的某斗士甲:
- 星矢最初的狀態是:NormalState
- 星矢被揍了1次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:DyingState
- 星矢被揍了2次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:UniverseState
- 星矢被揍了3次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:DyingState
- 星矢被揍了4次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:GoddessState
- 星矢被揍了5次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:NormalState
總結:狀態模式的缺點就是會弄出很多子類,如果狀態沒那么復雜,狀態規則改變的可能性比較小的話就不要用了