观察者模式的定义:
在对象之间定义一对多的依赖,当一个对象改变状态时,依赖它的对象都会收到通知,并自动更新。
说白了就像是:有一群人订了同一家报纸,当这个报纸出新版的时候,会派报童给每个订阅了自己的人一份最新的报纸,然后不同的订阅人收到报纸后,自己处理,可以看看新闻,可以叠成飞机,可以用来防止上厕所时没带纸。。。订阅者收到报纸后怎么样,已经不管这家报纸发行商的事了。
订阅人可以取消订阅,没订阅的人也可以加入订阅的行列。
WOW扫盲,写给没玩过WOW的java人们:
WOW:魔兽世界
BOSS:这个大家都知道,每个游戏都有BOSS,就是个怪物的首领
TANK:也就是大家常说的肉盾,把BOSS的仇恨吸引到自己身上来,好让其他人打BOSS
DPS:打手,BOSS打TANK,DPS打BOSS
Healther:治疗,俗称奶妈,BOSS打TANK,奶妈给TANK加血。
现在用这种模式来模拟一个WOW的插件。
假设,WOW中有一个BOSS,他的技能分两个阶段。
第一阶段的时候,只用TANK拉好了,DPS们只管打就是了,奶妈治疗TANK。
第二阶段的时候,BOSS会在地面上方火焰,TANK依然是拉好BOSS,但需要躲地上的火焰,DPS们依然是打BOSS,也需要躲火焰,奶妈这个时候不但要为TANK加血,也要为DPS加血(有的DPS可能被火烧到)。
我们要做的东西,就是为队长写一个插件,让这个插件可以自动给队里的每个角色分配任务。
我们希望BOSS在第一阶段的时候,奶妈可以自动收到一个提示“请全力治疗Tank。”,而DPS收到的提示却是“请全力输出BOSS。”
插件为每个玩家配置一个发信的工具,为了方便就叫话筒吧,话筒去对玩家发送消息。
我们可以把BOSS看做是一个被观察的主题,而小队中所有玩家对应的话筒都是观察者。一但BOSS进入了第一阶段,也就是BOSS状态变了,那么所有观察者(也就是话筒)都会受到相应的通知,并对自己对应的玩家发送消息。
现在看代码:
package com.subject;
import com.observer.I_Observer;
//被观察的主题的接口
public interface I_Subject {
//注册一个观察者
public void registerObserver(I_Observer o);
//删除一个观察者
public void removeObserver(I_Observer o);
//通知所有观察者
public void notifyObserver();
}
package com.subject;
import java.util.ArrayList;
import com.observer.I_Observer;
//假设这是插件用来检测BOSS状态的监听器。这里并没有实现监听功能。
public class BossListener implements I_Subject {
ArrayList<I_Observer> listOfObserver;
int status;
public BossListener() {
listOfObserver = new ArrayList<I_Observer>();
status = 1;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
this.notifyObserver();
}
//通知所有观察者,并告诉观察者自己当前的状态
@Override
public void notifyObserver() {
for (I_Observer o : listOfObserver) {
o.update(this.status);
}
}
@Override
public void registerObserver(I_Observer o) {
this.listOfObserver.add(o);
}
@Override
public void removeObserver(I_Observer o) {
int index = this.listOfObserver.indexOf(o);
if (index >= 0) {
this.listOfObserver.remove(index);
}
}
}
package com.observer;
//观察者的接口
public interface I_Observer {
//状态改变时执行的动作
public void update(int status);
}
package com.observer;
public abstract class Player implements I_Observer {
//玩家的名字
String name;
//在第一阶段时,对玩家的提示。
String suggestion1;
//在第二阶段时,对玩家的提示。
String suggestion2;
//在第三阶段时,对玩家的提示。
String suggestion3;
public String getSuggestion1() {
return suggestion1;
}
public void setSuggestion1(String suggestion1) {
this.suggestion1 = suggestion1;
}
public String getSuggestion2() {
return suggestion2;
}
public void setSuggestion2(String suggestion2) {
this.suggestion2 = suggestion2;
}
public String getSuggestion3() {
return suggestion3;
}
public void setSuggestion3(String suggestion3) {
this.suggestion3 = suggestion3;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//根据不同阶段,发送不同的通知消息。
public void update(int status) {
if (status == 1) {
System.out.println("插件提示:Boss进入了第一阶段," + this.getName()
+ suggestion1);
} else if (status == 2) {
System.out.println("插件提示:Boss进入了第二阶段," + this.getName()
+ suggestion2);
} else if (status == 3) {
System.out.println("插件提示:Boss已经死亡,恭喜" + suggestion3);
}
}
}
package com.observer;
public class Tank extends Player {
public Tank(String name) {
this.name = name;
this.name=name;
this.suggestion1 = "请保持BOSS的仇恨";
this.suggestion2 = "请保持BOSS的仇恨并躲好地上的火焰。";
this.suggestion3 = ",BOSS已经死亡。";
}
//通知的逻辑已经在父类写过了,这里只用更改自己通知时的消息就行了
@Override
public void update(int status) {
super.update(status);
}
}
package com.observer;
public class DPS extends Player {
public DPS(String name)
{
this.name=name;
this.suggestion1 = "请全力输出BOSS。";
this.suggestion2 = "请全力输出BOSS并躲好地上的火焰。";
this.suggestion3 = ",BOSS已经死亡。";
}
@Override
public void update(int status) {
super.update(status);
}
}
package com.observer;
public class Healther extends Player {
public Healther(String name) {
this.name = name;
this.suggestion1 = "请全力治疗Tank。";
this.suggestion2 = "请对全团治疗,保持团血在百分之50以上。";
this.suggestion3 = ",BOSS已经死亡。";
}
@Override
public void update(int status) {
super.update(status);
}
}
测试类:
package com.test;
import com.observer.DPS;
import com.observer.Healther;
import com.observer.Tank;
import com.subject.BossListener;
public class Test {
public static void main(String[] args) {
BossListener listener =new BossListener();
listener.registerObserver(new Tank("MT"));
listener.registerObserver(new Tank("2T"));
listener.registerObserver(new DPS("DPS1"));
listener.registerObserver(new Healther("Healther1"));
listener.setStatus(1);
listener.setStatus(2);
listener.setStatus(3);
}
}
插件提示:Boss进入了第一阶段,MT请保持BOSS的仇恨
插件提示:Boss进入了第一阶段,2T请保持BOSS的仇恨
插件提示:Boss进入了第一阶段,DPS1请全力输出BOSS。
插件提示:Boss进入了第一阶段,Healther1请全力治疗Tank。
插件提示:Boss进入了第二阶段,MT请保持BOSS的仇恨并躲好地上的火焰。
插件提示:Boss进入了第二阶段,2T请保持BOSS的仇恨并躲好地上的火焰。
插件提示:Boss进入了第二阶段,DPS1请全力输出BOSS并躲好地上的火焰。
插件提示:Boss进入了第二阶段,Healther1请对全团治疗,保持团血在百分之50以上。
插件提示:Boss已经死亡,恭喜,BOSS已经死亡。
插件提示:Boss已经死亡,恭喜,BOSS已经死亡。
插件提示:Boss已经死亡,恭喜,BOSS已经死亡。
插件提示:Boss已经死亡,恭喜,BOSS已经死亡。
看完这些代码和执行结果,再回头看一下观察者模式的定义:
在对象之间定义一对多的依赖,当一个对象改变状态时,依赖它的对象都会收到通知,并自动更新。
多个观察者依赖同一个BOSS监听器,BOSS监听器监听到BOSS状态改变,则通知所有话筒,这些观察者做出了各自的反应。
当然,写这个主要是为了巩固观察者模式,WOW插件只是个例子,真正的WOW插件是很复杂的。。。
最后,身为一个WOWer向所有WOW插件开发者敬礼。
分享到:
相关推荐
wow313插件 整合插件,功能好用但是没有大脚清晰
WOW插件制作指南 pdf版,分享书籍
WOW插件制作指南PDF+WOW魔兽世界的APIs教程。
WOW插件制作指南PDF+WOW魔兽世界的APIs教程。很详细很详细很详细
WoW插件管理器.rar WoW插件管理器.rar WoW插件管理器.rar WoW插件管理器.rar WoW插件管理器.rar WoW插件管理器.rar
本文将以一般的软件编程的眼光审视魔兽插件。剥去其难解的外皮,让你有个清晰的大致了解。 1.程序员快速入手指南 1.引言 2.魔兽插件的架构 3.TOC —— 工程描述文件 4.XML —— 屏幕布局描述文件 1.XML文件主要内容...
Wow.js是javascript动画插件,经常配合animate.css一起使用。动画效果会在元素第一次出现在页面中时起作用。 引入wow.js 在需要使用的元素上添加class=”wow” 使用js初始化
绝对经典 和完整~~WOWAPI和插件制作
网页翻滚特效插件。网页翻滚特效插件。网页翻滚特效插件。网页翻滚特效插件。
【1】用 LUA解释器 实现魔兽世界 数学表达式计算插件 支持通用运算符和优先级 WoW Lua Math 库函数 以及 WoW Lua 环境变量 测试用例: /calc random(1,16) / 0x10 /calc log10(10) - log(exp(1)) /calc PI - rad...
css动画效果 wow插件需要的wow.min.js和animate.css
WOW简易基础入门插件、一个BUTTON、一个功能,下载放到插件目录就可以用,登陆后左下角有一个BUTTON1按钮,鼠标移动上去后统计背包物品。
WowLua 是一个在魔兽世界里边运行 Lua 脚本的编辑工具环境,他功能包括: 交互式 Lua 解释器 多页脚本编辑器。 语法着色 输出重定向到 WowLua 的输出窗口 WowLua 的输出窗口 /wowlua 或 /lua 打开 WowLua。 /...
SRS WOW HD音效插件很强大,SRS SRS(Sound Retrieval System)是由SRS研究所开发的、最具代表性的3D立体声技术。该技术的核心是可以利用2个扬声器获得环绕立体声的效果。更具体一点说,声波在周边各空间点都有其特定...
博学者插件EveryQuest (12个).rar
wow.js是一个JavaScript库,用于制作网站上的滚动动画效果。它可以帮助您为网站添加动态和视觉吸引力,并使用户在滚动时感到更加舒适和流畅。...使用wow.js可以轻松地为您的网站增加动态和互动性,提高用户体验。
易语言源码易语言WoW插件管理器源码.rar
wow.js 动态效果插件
魔兽世界lua插件开发教程
Wow.js是javascript动画插件,经常配合animate.css一起使用。动画效果会在元素第一次出现在页面中时起作用。 引入wow.js 在需要使用的元素上添加class=”wow” 使用js初始化