观察者模式定义对象的一种一对多的依赖关系。当一个对象的状态发生改变时。全部依赖于它的对象都会得到通知并被自己主动更新。

一个简单的样例是。在星际争霸的虫族中有一个0基础单位叫做跳狗(Zergling),玩家能够在研究中心为它升级“肾上腺素”,升级之后,跳狗的攻击速度会翻倍。在这个模型中,我们能够看出。全部的跳狗都依赖于研究中心,当研究中心研究出肾上腺素后,通知每个跳狗单位,它们被迫进行自我更新——升级速度加倍。在观察者模型中。我们称研究中心为目标(Subject),而跳狗为观察者(Observer)。观察者观察目标的变化,假设目标发生了变化,那么观察者自身也会跟着变化。

下面是Java代码:

  1. import java.util.ArrayList;
  2.  
  3. abstract class Subject{
  4. ArrayList<Observer> observers = new ArrayList<Observer>();
  5. public void attach(Observer observer){
  6. if (!observers.contains(observer))
  7. observers.add(observer);
  8. }
  9. public void detach(Observer observer){
  10. if (observers.contains(observer))
  11. observers.remove(observer);
  12. }
  13. protected void notifyObservers(){
  14. for (Observer o : observers){
  15. o.update(this);
  16. }
  17. }
  18. }
  19.  
  20. abstract class Observer{
  21. Subject subject;
  22. public Observer(Subject subject){
  23. this.subject = subject;
  24. subject.attach(this);
  25. }
  26. abstract void update(Subject subject);
  27. }
  28.  
  29. class AdrenalUpgrade extends Subject{
  30. public void upgrade(){
  31. notifyObservers();
  32. }
  33. }
  34.  
  35. class Zergling extends Observer {
  36. public Zergling(Subject subject) {
  37. super(subject);
  38. }
  39.  
  40. public void update(Subject subject) {
  41. if (subject == this.subject){
  42. System.out.println("Zergling的肾上腺素被刺激,攻击速度翻倍。");
  43. }
  44. }
  45. }
  46.  
  47. public class ObserverExample
  48. {
  49. public static void main(String[] args) {
  50. AdrenalUpgrade adrenalUpgrade = new AdrenalUpgrade();
  51. Zergling z1 = new Zergling(adrenalUpgrade);
  52. Zergling z2 = new Zergling(adrenalUpgrade);
  53. Zergling z3 = new Zergling(adrenalUpgrade);
  54. Zergling z4 = new Zergling(adrenalUpgrade);
  55. Zergling z5 = new Zergling(adrenalUpgrade);
  56. Zergling z6 = new Zergling(adrenalUpgrade);
  57. Zergling z7 = new Zergling(adrenalUpgrade);
  58. adrenalUpgrade.upgrade();
  59. }
  60. }

Subject的是目标的基类,它能够attach或detach一个Observer。Subject含有一个List用于记录自己被哪些Observer依赖。当自身的状态改变时。会依次调用每个Observer的update()方法。

比如在main方法中,我们分别建立了z1、z2……z7共7个Zergling单位,它们都attach到了AdrenalUpgrade上,当AdrenalUpgrade调用了upgrade()时,会给每个Zergling发出通知,因此程序的执行结果为:

Zergling的肾上腺素被刺激,攻击速度翻倍!

Zergling的肾上腺素被刺激,攻击速度翻倍!

Zergling的肾上腺素被刺激,攻击速度翻倍!

Zergling的肾上腺素被刺激。攻击速度翻倍。

Zergling的肾上腺素被刺激。攻击速度翻倍!

Zergling的肾上腺素被刺激,攻击速度翻倍。

Zergling的肾上腺素被刺激,攻击速度翻倍。

以上就是观察者模式的一个样例。有兴趣的同学能够看一看MVC(C#)结构。它可能是观察者模式中最有名的结构之中的一个了。

Java设计模式之从[星际争霸的兵种升级]分析观察者(Observer)模式的更多相关文章

  1. Java 实现观察者(Observer)模式

    1. Java自带的实现 类图 /** * 观察目标 继承自 java.util.Observable * @author stone * */ public class UpdateObservab ...

  2. Head First 设计模式 —— 02. 观察者 (Observer) 模式

    思考题 在我们的一个实现中,下列哪种说法正确?(多选) P42 public class WeatherDate { // 实例变量声明 public void measurementsChanged ...

  3. 面向对象设计模式——观察者(OBSERVER)模式

    定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.  Observer模式描述了如何建立这种关系.这一模式中的关键对象是目标(subject ...

  4. 设计模式之观察者(OBSERVER)模式

    定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.  Observer模式描述了如何建立这种关系.这一模式中的关键对象是目标(subject ...

  5. java观察者(Observer)模式

    观察者模式:     试想,在电子商务网站上,一个用户看中了一件一份,但是当时衣服的价格太贵,你需要将衣服收藏,以便等衣服降价时自动通知该用户.这里就是典型的观察模式的例子.     1.观察者模式的 ...

  6. 《Head First 设计模式》ch.2 观察者(Observer)模式

    观察者模式 定义了对象之间一对多以来,这样一来,当一个对象改变状态时,它所有的依赖者都会收到通知并自动更新 设计原则-松耦合 松耦合将对象之间的互相依赖降到了最低——只要他们之间的接口仍被遵守 观察者 ...

  7. 设计模式C++描述----04.观察者(Observer)模式

    一. 概述 Observer 模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,依赖这个“一”的多也能够同步改变. Sbuject 相当于 ...

  8. 20. 星际争霸之php设计模式--适配器模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  9. 17. 星际争霸之php设计模式--职责链模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

随机推荐

  1. [Apple开发者帐户帮助]六、配置应用服务(1.2)Apple Pay:在网络上配置Apple Pay

    网上Apple Pay允许用户在您的网络应用中购买商品和服务. 首先在您的开发者帐户中创建一个商家标识符,该标识符可以将Apple Pay唯一标识为能够接受付款的商家.您可以为多个本机和Web应用程序 ...

  2. mybatis的二级缓存

    在mybatis主配置文件里configuration标签里添加 <settings> <setting name="cacheEnabled" value=&q ...

  3. thinkphp3.2 验证码生成和点击刷新验证码

    生成验证码的时候: public function verify_c(){ $Verify = new \Think\Verify(); $Verify->fontSize = 18; $Ver ...

  4. mvp 不错的链接

    http://www.imooc.com/wenda/detail/216700 http://www.cnblogs.com/mybkn/archive/2012/04/12/2443676.htm ...

  5. POJ 2823 线段树 Or 单调队列

    时限12s! 所以我用了线段树的黑暗做法,其实正解是用单调队列来做的. //By SiriusRen #include <cstdio> #include <cstring> ...

  6. B - Helpful Maths

    Problem description Xenia the beginner mathematician is a third year student at elementary school. S ...

  7. Java 类加载器及加载Class字节码

    参考来源:http://www.cnblogs.com/fingerboy/p/5456371.html       java笔记--理解java类加载器以及ClassLoader类 参考来源:htt ...

  8. Discuze修改用户名长度限制

    第一步,在网站 uc_client\model 目录下的 user.php文件中,找到如下代码: ? 1 if($len > 15 || $len < 3 || preg_match(&q ...

  9. MVC微信浏览器图片上传(img转Base64)

    因公司业务需要,需要做一个微信公众号里的图片上传功能,主要用到的技术就是 img转base64 上到服务器 话不多说, 贴代码 先看前端显示出来的东西 OK 图片不重要,看代码 <!--微信图片 ...

  10. Django中的bug总结

    1.插入数据库的时候,少写一个字段.ps:看准数据库的字段,是不是非空,是不是外键. 2.当同一个视图中需要连续操作两个数据表时,先看好两个表的外键之间的关系,再进行操作表.比如:一个订单表order ...