第70章
小a:“讲了那么多,师兄如果能给我举个例子那就更好了。”
大b:“那我给你举个圣斗士星矢的状态模式和观察者模式的例子吧!”
星矢:动画片《圣斗士星矢》的男猪蹄,超级小强,怎么打也打不死。
雅典娜:动画片《圣斗士星矢》的女猪蹄,自称女神,手下有88个男人为他卖命。
状态模式:为了方便的控制状态的变化,避免一堆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(){
//调用当前状态的被打方法?反过来改变自己的状态
state.hit();
}
publicstringstatus(){
//当前状态名
returnstate.status();
}
protectedvoidsetstate(saiyastatestate){
laststate=this.state;
this.state=state;
//观察者模式
setchanged();
notifyobservers(“星矢状态变化”);
}
publicstringgetlaststatus(){
returnlaststate.status();
}
publicclasssaiyaextendsobservable{
//定义星矢的四种状态
publicfinalsaiyastatenormal=newnormalstate(this);
publicfinalsaiyastatedying=newdyingstate(this);
publicfinalsaiyastategoddess=newgoddessstate(this);
publicfinalsaiyastateuniverse=newuniversestate(this);
privatesaiyastatestate=normal;
privatesaiyastatelaststate=null;
publicvoidhit(){
//调用当前状态的被打方法反过来改变自己的状态
state.hit();
}
publicstringstatus(){
//当前状态名
returnstate.status();
}
protectedvoidsetstate(saiyastatestate){
laststate=this.state;
this.state=state;
//观察者模式
setchanged();
notifyobservers(“星矢状态变化”);
}
publicstringgetlaststatus(){
returnlaststate.status();
}
星矢的状态
java代码
publicabstractclasssaiyastate{
protectedsaiyasaiya;
publicsaiyastate(saiyasaiya){
this.saiya=saiya;
}
publicstringstatus(){
stringname=getclass().getname();
returnname.substring(name.lastindexof()+1);
}
//星矢被打了
publicabstractvoidhit();
}
publicabstractclasssaiyastate{
protectedsaiyasaiya;
publicsaiyastate(saiyasaiya){
this.saiya=saiya;
}
publicstringstatus(){
stringname=getclass().getname();
returnname.substring(name.lastindexof()+1);
}
//星矢被打了
publicabstractvoidhit();
}
在每种状态里面实现被打的时候所需要更改的状态,例如小宇宙爆发状态下被打java代码
publicclassuniversestateextendssaiyastate{
/**
*@paramsaiya
*/
publicuniversestate(saiyasaiya){
super(saiya);
}
/*小宇宙爆发状态被打进入瀕死状态
*
*/
publicvoidhit(){
saiya.setstate(saiya.dying);
}
}
publicclassuniversestateextendssaiyastate{
/**
*@paramsaiya
*/
publicuniversestate(saiyasaiya){
super(saiya);
}
/*小宇宙爆发状态被打进入瀕死状态
*
*/
publicvoidhit(){
saiya.setstate(saiya.dying);
}
}
雅典娜在一边看,星矢每次被打她都要给星矢加油,她是个观察者,星矢是被观察者,这里星矢实现java.util.observable,每次被打hit就notifyobservers,雅典娜就加油。
java代码
publicclassathenaimplementsobserver{
/*我是雅典娜我是观察者
*
*/
publicvoidupdate(observablearg0,objectarg1){
system.out.println(“雅典娜说:星矢加油啊!”);
}
}
publicclassathenaimplementsobserver{
/*我是雅典娜我是观察者
*
*/
publicvoidupdate(observablearg0,objectarg1){
system.out.println(“雅典娜说:星矢加油啊!”);
}
}
总的来看这个过程就是这样子:
java代码
publicclassstatemain{
publicstaticvoidmain(string[]args){
saiyasaiya=newsaiya();
observerathena=newathena();
saiya.addobserver(athena);
system.out.println(星矢最初的状态是:+saiya.status());
for(inti=0;i