前天朋友
蛋殼老兄推薦了這篇文章給我,挺好玩的。
挺喜歡里面的挨打、小宇宙爆發(fā)情節(jié),相信圣斗士的fans都會(huì)喜歡,特此轉(zhuǎn)載。
來源:http://www.javaeye.com/topic/212142
星矢:動(dòng)畫片《圣斗士星矢》的男豬腳,超級(jí)小強(qiáng),怎么打也打不死。
雅典娜:動(dòng)畫片《圣斗士星矢》的女豬腳,自稱女神,手下有88個(gè)男人為他賣命。
狀態(tài)模式:為了方便的控制狀態(tài)的變化,避免一堆IF/ELSE,以及狀態(tài)規(guī)則改變的時(shí)避免代碼改動(dòng)的混亂。
觀察者模式:一個(gè)被觀察者一動(dòng),多個(gè)觀察者跟著動(dòng),經(jīng)常用于界面UI。
話說星矢和很強(qiáng)的某斗士甲對(duì)打,雅典娜在一邊看,星矢總是挨揍,每次挨揍完之后星矢的狀態(tài)總是會(huì)發(fā)生一些變化:
正常--挨打--瀕死--挨打--小宇宙爆發(fā)--挨打--瀕死--挨打--女神護(hù)體--挨打(星矢無敵了,打也沒用,戰(zhàn)斗結(jié)束)--正常
以上狀態(tài)轉(zhuǎn)變用狀態(tài)模式來表現(xiàn),一個(gè)Saiya類代表星矢,一個(gè)SaiyaState代表他的狀態(tài),SaiyaState下面有多個(gè)子類,分別代表星矢的多種狀態(tài),如正常NORMAL、瀕死DYING、小宇宙爆發(fā)UNIVERSE、女神護(hù)體GODDESS,即把狀態(tài)抽象成對(duì)象,在每種狀態(tài)里面實(shí)現(xiàn)被打的時(shí)候所需要更改的狀態(tài),這樣就避免了每次被打都要進(jìn)行一次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("星矢狀態(tài)變化");
- }
-
- public String getlastStatus(){
- return laststate.status();
- }
public class Saiya extends Observable {
//定義星矢的四種狀態(tài)
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(){
//調(diào)用當(dāng)前狀態(tài)的被打方法 反過來改變自己的狀態(tài)
state.hit();
}
public String status(){
//當(dāng)前狀態(tài)名
return state.status();
}
protected void setState(SaiyaState state){
laststate=this.state;
this.state=state;
//觀察者模式
setChanged();
notifyObservers("星矢狀態(tài)變化");
}
public String getlastStatus(){
return laststate.status();
}
星矢的狀態(tài)
- 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();
}
在每種狀態(tài)里面實(shí)現(xiàn)被打的時(shí)候所需要更改的狀態(tài),例如小宇宙爆發(fā)狀態(tài)下被打
- 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);
}
/* 小宇宙爆發(fā)狀態(tài)被打進(jìn)入瀕死狀態(tài)
*
*/
public void hit() {
saiya.setState( saiya.DYING);
}
}
雅典娜在一邊看,星矢每次被打她都要給星矢加油,她是個(gè)觀察者,星矢是被觀察者,這里星矢實(shí)現(xiàn)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("雅典娜說:星矢加油啊!!!");
}
}
總的來看 這個(gè)過程就是這樣子:
- public class StateMain {
- public static void main(String[] args) {
-
- Saiya saiya = new Saiya();
- Observer athena = new Athena();
- saiya.addObserver(athena);
- System.out.println("星矢最初的狀態(tài)是:" + saiya.status());
- for (int i = 0; i < 5; i++) {
- System.out.println("星矢被揍了" + (i + 1) + "次");
- saiya.hit();
- System.out.println("星矢現(xiàn)在的狀態(tài)是:" + 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("星矢最初的狀態(tài)是:" + saiya.status());
for (int i = 0; i < 5; i++) {
System.out.println("星矢被揍了" + (i + 1) + "次");
saiya.hit();
System.out.println("星矢現(xiàn)在的狀態(tài)是:" + saiya.status());
}
}
}
結(jié)果星矢在雅典娜的幫助下,有驚無險(xiǎn)的戰(zhàn)勝了很強(qiáng)的某斗士甲:
- 星矢最初的狀態(tài)是:NormalState
- 星矢被揍了1次
- 雅典娜說:星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:DyingState
- 星矢被揍了2次
- 雅典娜說:星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:UniverseState
- 星矢被揍了3次
- 雅典娜說:星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:DyingState
- 星矢被揍了4次
- 雅典娜說:星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:GoddessState
- 星矢被揍了5次
- 雅典娜說:星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:NormalState
星矢最初的狀態(tài)是:NormalState
星矢被揍了1次
雅典娜說:星矢加油啊!!!
星矢現(xiàn)在的狀態(tài)是:DyingState
星矢被揍了2次
雅典娜說:星矢加油啊!!!
星矢現(xiàn)在的狀態(tài)是:UniverseState
星矢被揍了3次
雅典娜說:星矢加油啊!!!
星矢現(xiàn)在的狀態(tài)是:DyingState
星矢被揍了4次
雅典娜說:星矢加油啊!!!
星矢現(xiàn)在的狀態(tài)是:GoddessState
星矢被揍了5次
雅典娜說:星矢加油啊!!!
星矢現(xiàn)在的狀態(tài)是:NormalState
總結(jié):狀態(tài)模式的缺點(diǎn)就是會(huì)弄出很多子類,如果狀態(tài)沒那么復(fù)雜,狀態(tài)規(guī)則改變的可能性比較小的話就不要用了
posted on 2008-07-09 14:54
kenlee14 閱讀(1620)
評(píng)論(10) 編輯 收藏