`
beckrabbit
  • 浏览: 129420 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

圣斗士星矢的状态模式和观察者模式

阅读更多
星矢:动画片《圣斗士星矢》的男猪脚,超级小强,怎么打也打不死。
雅典娜:动画片《圣斗士星矢》的女猪脚,自称女神,手下有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


总结:状态模式的缺点就是会弄出很多子类,如果状态没那么复杂,状态规则改变的可能性比较小的话就不要用了
分享到:
评论
24 楼 rmi 2009-05-10  
java.swing 包中的监听
JButton login=new JButton();
login.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
//事件发生后要执行的代码
}
});

按钮是被观察者,那观察者在哪,怎么通知的呢,这里的ActionEvent 是何时构造的呢
ActionEvent(Object source, int id, String command)
ActionEvent(Object source, int id, String command, int modifiers)
ActionEvent(Object source, int id, String command, long when, int modifiers)
用的哪一个构造方法

看过源码只知道 将ActionListener.class和ActionListener的实现类放到对象数组中
就是想不出UML图 是什么样的
注:我的当前类未实现ActionListener接口
23 楼 wq13480 2009-01-16  
你太有才了.接合卡通.有创意
22 楼 NumberWen 2009-01-15  
Nighthaven 写道
呃,长见识了,原来java里面有Observer这种东西。这个东西和EventListener是个什么关系呢?啥时候用哪一种?

建议可以看看awt的button设计方式,应该能够比较客观地讲解你所提的问题
21 楼 nba520pz 2009-01-14  
Observer 模式可以自己写的!
没必要使用JDK的,为了可以定制自己
需要的功能!
20 楼 leeldy 2009-01-14  
Observer和EventListener是什么东东?
LZ厉害,程序可以说的这么有声有色有味道
我对LZ的敬仰犹如滔滔江水连绵不绝,一发不可收拾。。。
19 楼 suliuyes 2008-12-30  
人才。收藏、
顺便问牛牛们一个问题,对于技术不是很精通,项目经验还少的人来讲,有没有必要研究设计模式?
18 楼 dracularking 2008-12-30  
呵呵很好的创意啊 观察者模式还有哪些更深入的挖掘点
p.s.saiya=>seiya
17 楼 lijie1819 2008-12-10  
楼主对模式理解不错,会举一反三!我想是在看过《head first 设计模式》这本书后产生出的设计思路的吧,佩服楼主的动手能力。
16 楼 zhangzuohai 2008-11-04  
向高手学习!
15 楼 sea7 2008-11-04  
citi.sh 写道
补充上DyingState类:

public class DyingState extends SaiyaState{

	public DyingState(Saiya saiya) {   
        super(saiya);   
  
    }   

  
    public void hit() {   
        //是普通状态下被打成瀕死状态时 会变成小宇宙爆发状态
    	if (saiya.getlastStatus().equals("NormalState")) {
        saiya.setState( saiya.UNIVERSE);   
        //是小宇宙爆发状态下被打成瀕死状态时 会变成女神副体状态
    	}else if(saiya.getlastStatus().equals("UniverseState")){
        saiya.setState( saiya.GODDESS);
    	}
    } 
}


画蛇添足!!
14 楼 sigon 2008-10-16  
厉害,佩服lz
13 楼 jj_sof 2008-10-16  
看完都大家的回帖才知道是介绍设计模式
12 楼 black_zerg 2008-10-15  
这几个类之间强耦合,还互相引用看着很死锁的样子
11 楼 xiaoqiang01 2008-10-10  
感谢楼主啊..有关状态模式的还有一篇也不错:

http://www.iteye.com/topic/212553

10 楼 Nietzsche 2008-10-06  
你好LZ,我将你的这篇文章转成C#,希望你不会介意,谢谢
9 楼 country3721 2008-08-25  
状态之间是否耦合性可以缩小一些?我添加了一个LinkedList将所有的状态放进去。然后用一个保持状态的类持有该List,通过该类来进行状态的变化。我感觉这应该是一个简单的实现。我再想如果状态是一个有限自动机的形式应该怎么办呢?用Tree?
8 楼 xufei0110 2008-07-17  
java 提供的观察者模式用的是继承。

public class Saiya extends Observable { 

其实还是有些坏处的。

所以用的时候还是要小心一些的。
7 楼 zlrzc 2008-07-07  
长见识了~~

把动画片和模式联系起来~  楼主的创意太好了~  值得学习!!!
6 楼 lubezhang 2008-07-07  
涨见识了,原来星矢还可以这么玩儿。以后如果记不清Observer,想想星矢就可以了,谢谢楼主的创意。

希望漫画迷们多多出些这样的例子,比较容易记忆。
5 楼 hyxw5890 2008-07-07  
关于Java里面Observer模式和EventListener的区别下面这篇文章说的很清楚

http://www.iteye.com/topic/182643

相关推荐

    圣斗士星矢——黄金十二宫(游戏+源码)重发

    《圣斗士星矢——黄金十二宫》是一款以经典动漫《圣斗士星矢》为背景的游戏,结合了丰富的剧情和战斗元素。这次提供的资源包括游戏的可执行文件"seiya.exe"以及游戏源码"SeiyaSource.rar",这对于想要深入理解游戏...

    圣斗士星矢——VB黄金十二宫(游戏+源码)

    在这款游戏中,开发者利用VB的控件、函数和过程,模拟了圣斗士星矢中的黄金十二宫场景,玩家可以通过控制角色,挑战各个宫殿的守卫,体验原作的冒险历程。 游戏的源码是理解VB编程思想和技巧的重要窗口。通过对源码...

    圣斗士星矢ol完整云服务器架设.txt

    完整云服务器架设

    【翻译】圣斗士星矢:圣域传说 制作介绍 特效合成等1

    总结而言,《圣斗士星矢:圣域传说》的制作展现了动画电影在特效制作、工具开发和流程优化方面的创新。它不仅为业界人士提供了技术实践的参考,也为普通观众带来了震撼的视觉体验。影片制作的成功,不仅是因为背后...

    圣斗士网站

    "圣斗士网站"就是这样一款以经典动漫《圣斗士星矢》为主题的网页设计项目,旨在为粉丝们提供一个交流、分享与回忆的平台。本文将深入探讨如何运用网页设计技巧和工具,如Dreamweaver,来打造这样一个充满激情与力量...

    圣斗士星失天界篇花絮

    圣斗士天界篇花絮 圣斗士天界篇花絮 圣斗士天界篇花絮 圣斗士天界篇花絮 圣斗士天界篇花絮

    游戏素材(圣斗士格斗图)

    圣斗士星矢是一部经典的日本动漫,其角色拥有各种独特的技能和战斗风格,因此在游戏化的过程中,这些元素将被转化为可交互的游戏资源。 "afrodita"、"andromeda"、"Aioria"和"14124"是压缩包内的子文件名,这些名称...

    OBLOG 圣斗士

    首先,模板中的“圣斗士”主题意味着它可能包含了与《圣斗士星矢》动漫相关的视觉元素,如角色插图、动漫风格的图形以及与故事相关的色彩搭配。这样的设计不仅能够吸引动漫爱好者,还可以为网站增添独特的个性和情感...

    圣斗士星矢 Matlab Game.zip:圣斗士星斗格斗游戏-matlab开发

    用户应该运行saintseiya_att_sel.m 来开始格斗游戏。 用户可以随机获得一个圣人和一个敌人,并开始一对一的战斗。 每个圣人都有一个宇宙和生命(HP)属性。... 他们的中文名字是:星矢紫龙冰河瞬态一辉穆阿

    连连看,关卡版

    - 不断的版本更新和优化,可能会增加新的关卡、新的游戏模式或新的挑战,保持游戏的新鲜感。 - 社区互动和分享功能,允许玩家分享自己的成绩和经验,增加游戏的社交性。 总的来说,连连看关卡版在保留了经典游戏...

    算法实验报告 勇闯十二宫

    于是青铜圣斗士星矢决定冒死突破十二宫。 守卫十二宫的黄金圣斗士能在强大的星矢面前坚持的时间是不同的,星矢想让所有黄金圣斗士平均等待的时间最短,请问黄金圣斗士的最短平均等待时间是多少?

    圣斗士星矢测验:在React Alura入侵期间进行的简单测验

    具有样式组件的示例应用 此示例介绍了如何使用与样式不同的样式解决方案,还支持通用样式。... 在这种情况下,我们使用 。 为此,我们扩展了并将服务器端渲染的样式注入到&lt;head&gt; ,并且还添加了babel-plugin-...

    星座黄金圣斗士经典广告词.doc

    这篇文档虽然以《星座黄金圣斗士经典广告词》为标题,但实际上它是一种创意写作,将知名动漫角色“圣斗士星矢”中的角色与广告语结合,创造了一系列幽默诙谐的场景。这些广告词涉及了各种产品,如服装、食品、个人...

    天使之翼2代(chinese)

    《天使之翼2代》(又称《圣斗士星矢:黄金传说最后的任务》)是基于日本知名漫画《圣斗士星矢》改编的游戏。玩家在游戏中扮演不同的圣斗士,通过一系列战斗,挑战强大的敌人,体验原作的故事线。游戏的故事情节紧密...

    Xiuno BBS 高负载安全论坛 v2.1.0 Build20130830

    Xiuno 这个名字来源于圣斗士星矢白羊座的黄金圣斗士修罗,他的攻击速度和战斗力是十二宫最强的,他是速度和力量的化身; 在佛教里面,修罗为六道之一,英文:Shura,处于人道和天道之间的一道,半人半神,性情刚烈,...

    xiuno bbs 手机版插件 v1.3

    xiuno 这个名字来源于圣斗士星矢山羊座的黄金圣斗士修罗,他的攻击速度和战斗力是十二宫最强的,他是速度和力量的化身; 在佛教里面,修罗为六道之一,英文:Shura,处于人道和天道之间的一道,半人半神,性情刚烈,...

    matlab开发-圣西山塔布加姆齐普

    在本项目中,“matlab开发-圣西山塔布加姆齐普”指的是利用MATLAB这一强大的数值计算和编程环境来开发一个名为“圣西山塔布加姆齐普”的游戏,这款游戏似乎与圣斗士星矢("圣西娅打斗游戏")的世界观有关。...

    xiuno bbs 手机版插件 v1.3.zip

    xiuno 这个名字来源于圣斗士星矢山羊座的黄金圣斗士修罗,他的攻击速度和战斗力是十二宫最强的,他是速度和力量的化身; 在佛教里面,修罗为六道之一,英文:Shura,处于人道和天道之间的一道,半人半神,性情刚烈,...

    你已经死了!动漫界八大杀手人物盘点收集.pdf

    例如,夜神月(《死亡笔记》)、冥王哈迪斯(《圣斗士星矢》)、飞影(《幽游白书》)、健次郎(《北斗神拳》)和鲁鲁修(《叛逆的鲁鲁修》)等,都是动漫中知名的杀手或类似角色。 2. **夜神月**:作为《死亡笔记...

    李炎恢DreamWeaver视频教程的素材和源码

    至于"圣斗士星矢"和"火影忍者疾风传",这些可能是动漫主题的网页项目,你可以从中学习如何创建动态和引人入胜的粉丝站点,包括如何插入多媒体内容如视频和音频,以及如何构建社区论坛或评论系统。 最后,"专题:...

Global site tag (gtag.js) - Google Analytics