前天朋友
蛋殼老兄推薦了這篇文章給我,挺好玩的。
挺喜歡里面的挨打、小宇宙爆發情節,相信圣斗士的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 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 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 {
-
-
-
-
- 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,雅典娜就加油。
- 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("雅典娜說:星矢加油啊!!!");
}
}
總的來看 這個過程就是這樣子:
- 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());
}
}
}
結果星矢在雅典娜的幫助下,有驚無險的戰勝了很強的某斗士甲:
- 星矢最初的狀態是:NormalState
- 星矢被揍了1次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:DyingState
- 星矢被揍了2次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:UniverseState
- 星矢被揍了3次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:DyingState
- 星矢被揍了4次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:GoddessState
- 星矢被揍了5次
- 雅典娜說:星矢加油啊!!!
- 星矢現在的狀態是:NormalState
星矢最初的狀態是:NormalState
星矢被揍了1次
雅典娜說:星矢加油啊!!!
星矢現在的狀態是:DyingState
星矢被揍了2次
雅典娜說:星矢加油啊!!!
星矢現在的狀態是:UniverseState
星矢被揍了3次
雅典娜說:星矢加油啊!!!
星矢現在的狀態是:DyingState
星矢被揍了4次
雅典娜說:星矢加油啊!!!
星矢現在的狀態是:GoddessState
星矢被揍了5次
雅典娜說:星矢加油啊!!!
星矢現在的狀態是:NormalState
總結:狀態模式的缺點就是會弄出很多子類,如果狀態沒那么復雜,狀態規則改變的可能性比較小的話就不要用了
posted on 2008-07-09 14:54
kenlee14 閱讀(1619)
評論(10) 編輯 收藏