挺喜歡里面的挨打、小宇宙爆發(fā)情節(jié),相信圣斗士的fans都會(huì)喜歡,特此轉(zhuǎn)載。
來(lái)源: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。
話說(shuō)星矢和很強(qiáng)的某斗士甲對(duì)打,雅典娜在一邊看,星矢總是挨揍,每次挨揍完之后星矢的狀態(tài)總是會(huì)發(fā)生一些變化:
正常--挨打--瀕死--挨打--小宇宙爆發(fā)--挨打--瀕死--挨打--女神護(hù)體--挨打(星矢無(wú)敵了,打也沒(méi)用,戰(zhàn)斗結(jié)束)--正常
以上狀態(tài)轉(zhuǎn)變用狀態(tài)模式來(lá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 {
- //定義星矢的四種狀態(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)的被打方法 反過(guò)來(lá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();
- }
在每種狀態(tài)里面實(shí)現(xiàn)被打的時(shí)候所需要更改的狀態(tài),例如小宇宙爆發(fā)狀態(tài)下被打
- 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("雅典娜說(shuō):星矢加油啊!!!");
- }
- }
總的來(lái)看 這個(gè)過(guò)程就是這樣子:
- 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é)果星矢在雅典娜的幫助下,有驚無(wú)險(xiǎn)的戰(zhàn)勝了很強(qiáng)的某斗士甲:
- 星矢最初的狀態(tài)是:NormalState
- 星矢被揍了1次
- 雅典娜說(shuō):星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:DyingState
- 星矢被揍了2次
- 雅典娜說(shuō):星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:UniverseState
- 星矢被揍了3次
- 雅典娜說(shuō):星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:DyingState
- 星矢被揍了4次
- 雅典娜說(shuō):星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:GoddessState
- 星矢被揍了5次
- 雅典娜說(shuō):星矢加油啊!!!
- 星矢現(xiàn)在的狀態(tài)是:NormalState
總結(jié):狀態(tài)模式的缺點(diǎn)就是會(huì)弄出很多子類,如果狀態(tài)沒(méi)那么復(fù)雜,狀態(tài)規(guī)則改變的可能性比較小的話就不要用了