观察者模式的定义:[color=red]在对象之间定义一对多的依赖,当一个对象改变状态时,依赖它的对象都会收到通知,并自动更新。[/color]

说白了就像是:有一群人订了同一家报纸,当这个报纸出新版的时候,会派报童给每个订阅了自己的人一份最新的报纸,然后不同的订阅人收到报纸后,自己处理,可以看看新闻,可以叠成飞机,可以用来防止上厕所时没带纸。。。订阅者收到报纸后怎么样,已经不管这家报纸发行商的事了。
订阅人可以取消订阅,没订阅的人也可以加入订阅的行列。

[color=blue]WOW扫盲,写给没玩过WOW的java人们:
WOW:魔兽世界
BOSS:这个大家都知道,每个游戏都有BOSS,就是个怪物的首领
TANK:也就是大家常说的肉盾,把BOSS的仇恨吸引到自己身上来,好让其他人打BOSS
DPS:打手,BOSS打TANK,DPS打BOSS
Healther:治疗,俗称奶妈,BOSS打TANK,奶妈给TANK加血。[/color]

现在用这种模式来模拟一个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已经死亡。

看完这些代码和执行结果,再回头看一下观察者模式的定义:
[color=red]在对象之间定义一对多的依赖,当一个对象改变状态时,依赖它的对象都会收到通知,并自动更新。 [/color]

多个观察者依赖同一个BOSS监听器,BOSS监听器监听到BOSS状态改变,则通知所有话筒,这些观察者做出了各自的反应。

当然,写这个主要是为了巩固观察者模式,WOW插件只是个例子,真正的WOW插件是很复杂的。。。

[color=blue]最后,身为一个WOWer向所有WOW插件开发者敬礼。[/color]

观察者模式和模拟wow插件的例子相关推荐

  1. WOW插件:ShortRobot 1.21 发布(2006.10.3)

    下载:http://files.cnblogs.com/simonw/ShortRobot.rar 作者:simonw, [2区 暗影之月 人类牧师 民族英雄] Email::i-simon AT m ...

  2. astar插件下载 就行_PS模拟下雨插件下载 一键为照片添加下雨效果 小伙伴们收货啦...

    今天整理文件,找出来一个挺好玩的PS扩展插件,BBtools出品的模拟下雨插件,可以为照片添加下雨效果,其实就是一些动作的整合,不过偶尔用用还是挺有意思的,插件可以手动控制下雨的角度.密度.风速.雨量 ...

  3. 【web】模拟QQ炫舞例子(键盘)

    模拟QQ炫舞例子(键盘) 效果图 从1个到10个,模拟关卡升级从简单到难,图为10个的 代码 <!DOCTYPE html> <html lang="en"> ...

  4. WOW插件:ShortUnitFrame 2.1 发布(2007.7.17)

    作者: simonw From CWDG  2区 暗影之月, 人类牧师, 民族英雄 simonw的wow插件技术博客: http://blog.cwowaddon.com/simonw 1. 玩家窗体 ...

  5. html.gmt文件,基于格林威治标准时间(GMT)的jQuery模拟时钟插件

    jClocksGMT是一款基于格林威治标准时间(GMT)的jQuery模拟时钟插件.你可以调整时区的偏移值来显示相应地区的时间,还能够自动转换夏令时时间.它的特点还有: 模拟时钟. 电子时钟. 可以显 ...

  6. 实现 WOW 插件的简单步骤

    一.导出WOW接口文件 1.      带参数运行wow.exe –console 2.      在游戏中按下"`/~"键 3.      在魔兽控制台下输入"expo ...

  7. java 观察者模式_重学 Java 设计模式:实战观察者模式「模拟类似小客车指标摇号过程,监听消息通知用户中签场景」...

    一.前言 知道的越多不知道的就越多 编程开发这条路上的知识是无穷无尽的,就像以前你敢说精通Java,到后来学到越来越多只想写了解Java,过了几年现在可能想说懂一点点Java.当视野和格局的扩大,会让 ...

  8. 软件设计模式(观察者模式)——模拟股票价格变动并绘制分时图和K线图

    一.观察者模式简介: 首先看百度百科上对观察者模式的简介:观察者模式(Observer)完美的将观察者和被观察的对象分离开.举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数 ...

  9. java 分时图_软件设计模式(观察者模式)——模拟股票价格变动并绘制分时图和K线图...

    一.观察者模式简介: 首先看百度百科上对观察者模式的简介:观察者模式(Observer)完美的将观察者和被观察的对象分离开.举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数 ...

  10. WOW插件:让ShortKey更好的为你工作(2006.10.4)

    ShortKey使用说明:http://simonw.cnblogs.com/archive/2005/10/20/258271.html 自ShortKey发布以来得到不少朋友的支持当然也包括疑问, ...

最新文章

  1. tm matlab,[转载]关于matlab中textread
  2. 第五十一条:当心字符串的连接性能
  3. 区块链创业者:谈企业级区块链落地,传统行业的崛起(分享实录)
  4. learning hdmi edid protocol
  5. L1、L2正则化详解
  6. Centos7下关闭带验证的MongoDB
  7. 一篇文章入门深度学习框架PyTorch
  8. php 微信小程序 循环 多选,微信小程序实现多选功能
  9. 关于ubuntu终端命令路径太长的问题
  10. 当我们谈AI时,到底该谈什么?
  11. 大数据里的婚姻:婚后两年,出轨高峰……
  12. Python中的异常处理Try...except...finally的使用的简单理解
  13. amos看拟合度在哪里看_360度看佛山战“疫”
  14. 人工智能之入门大数据
  15. 详解Camtasia的场景转换功能
  16. 多媒体计算机辅助英语教学,多媒体计算机辅助英语教学
  17. Origin 2022b | 更新及安装 | 中英文切换
  18. Go语言Revel框架 环境搭建
  19. 这是最好的企业管理手册
  20. 去掉word中的页眉

热门文章

  1. python内存泄漏_python 泄漏
  2. [渝粤教育] 西南科技大学 英语国家概况 在线考试复习资料
  3. 10658830让你的手机会唱歌
  4. MATLAB:gca、gcf、gco区别
  5. FPGA学习任意波函数信号发生器的设计(基于quartus II13.0)
  6. 串口抓包/截断工具的安装及使用详解
  7. 读取xlsx文件错误
  8. 解决wps缺少字体的问题
  9. Stata: 实时估计个股贝塔(beta)系数
  10. web of science /pubmed主要可检索字段