observer模式

观察器(Observer)范式解决的是一个相当普通的问题:由于某些对象的状态发生了改变,所以一组对象都需要更新,那么该如何解决?在Smalltalk的MVC(模型-视图-控制器)的“模型-视图”部分中,或在几乎等价的“文档-视图结构”中,大家可以看到这个问题。现在我们有一些数据(“文档”)以及多个视图,假定为一张图(Plot)和一个文本视图。若改变了数据,两个视图必须知道对自己进行更新,而那正是“观察器”要负责的工作。这是一种十分常见的问题,它的解决方案已包括进标准的java.util库中。
在Java中,有两种类型的对象用来实现观察器范式。其中,Observable类用于跟踪那些当发生一个改变时希望收到通知的所有个体——无论“状态”是否改变。如果有人说“好了,所有人都要检查自己,并可能要进行更新”,那么Observable类会执行这个任务——为列表中的每个“人”都调用notifyObservers()方法。notifyObservers()方法属于基础类Observable的一部分。
在观察器范式中,实际有两个方面可能发生变化:观察对象的数量以及更新的方式。也就是说,观察器范式允许我们同时修改这两个方面,不会干扰围绕在它周围的其他代码。
下面这个例子类似于第14章的ColorBoxes示例。箱子(Boxes)置于一个屏幕网格中,每个都初始化一种随机的颜色。此外,每个箱子都“实现”(implement)了“观察器”(Observer)接口,而且随一个Observable对象进行了注册。若点击一个箱子,其他所有箱子都会收到一个通知,指出一个改变已经发生。这是由于Observable对象会自动调用每个Observer对象的update()方法。在这个方法内,箱子会检查被点中的那个箱子是否与自己紧邻。若答案是肯定的,那么也修改自己的颜色,保持与点中那个箱子的协调。

 

//: BoxObserver.java
// Demonstration of Observer pattern using
// Java's built-in observer classes.
import java.awt.*;
import java.awt.event.*;
import java.util.*;

// You must inherit a new type of Observable:
class BoxObservable extends Observable {
  public void notifyObservers(Object b) {
    // Otherwise it won't propagate changes:
    setChanged();
    super.notifyObservers(b);
  }
}

public class BoxObserver extends Frame {
  Observable notifier = new BoxObservable();
  public BoxObserver(int grid) {
    setTitle("Demonstrates Observer pattern");
    setLayout(new GridLayout(grid, grid));
    for(int x = 0; x < grid; x++)
      for(int y = 0; y < grid; y++)
        add(new OCBox(x, y, notifier));
  }
  public static void main(String[] args) {
    int grid = 8;
    if(args.length > 0)
      grid = Integer.parseInt(args[0]);
    Frame f = new BoxObserver(grid);
    f.setSize(500, 400);
    f.setVisible(true);
    f.addWindowListener(
      new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          System.exit(0);
        }
      });
  }
}

class OCBox extends Canvas implements Observer {
  Observable notifier;
  int x, y; // Locations in grid
  Color cColor = newColor();
  static final Color[] colors = {
    Color.black, Color.blue, Color.cyan,
    Color.darkGray, Color.gray, Color.green,
    Color.lightGray, Color.magenta,
    Color.orange, Color.pink, Color.red,
    Color.white, Color.yellow
  };
  static final Color newColor() {
    return colors[
      (int)(Math.random() * colors.length)
    ];
  }
  OCBox(int x, int y, Observable notifier) {
    this.x = x;
    this.y = y;
    notifier.addObserver(this);
    this.notifier = notifier;
    addMouseListener(new ML());
  }
  public void paint(Graphics  g) {
    g.setColor(cColor);
    Dimension s = getSize();
    g.fillRect(0, 0, s.width, s.height);
  }
  class ML extends MouseAdapter {
    public void mousePressed(MouseEvent e) {
      notifier.notifyObservers(OCBox.this);
    }
  }
  public void update(Observable o, Object arg) {
    OCBox clicked = (OCBox)arg;
    if(nextTo(clicked)) {
      cColor = clicked.cColor;
      repaint();
    }
  }
  private final boolean nextTo(OCBox b) {
    return Math.abs(x - b.x) <= 1 &&
           Math.abs(y - b.y) <= 1;
  }
} ///:~

如果是首次查阅Observable的联机帮助文档,可能会多少感到有些困惑,因为它似乎表明可以用一个原始的Observable对象来管理更新。但这种说法是不成立的;大家可自己试试——在BoxObserver中,创建一个Observable对象,替换BoxObservable对象,看看会有什么事情发生。事实上,什么事情也不会发生。为真正产生效果,必须从Observable继承,并在衍生类代码的某个地方调用setChanged()。这个方法需要设置“changed”(已改变)标志,它意味着当我们调用notifyObservers()的时候,所有观察器事实上都会收到通知。在上面的例子中,setChanged()只是简单地在notifyObservers()中调用,大家可依据符合实际情况的任何标准决定何时调用setChanged()。
BoxObserver包含了单个Observable对象,名为notifier。每次创建一个OCBox对象时,它都会同notifier联系到一起。在OCBox中,只要点击鼠标,就会发出对notifyObservers()方法的调用,并将被点中的那个对象作为一个参数传递进去,使收到消息(用它们的update()方法)的所有箱子都能知道谁被点中了,并据此判断自己是否也要变动。通过notifyObservers()和update()中的代码的结合,我们可以应付一些非常复杂的局面。
在notifyObservers()方法中,表面上似乎观察器收到通知的方式必须在编译期间固定下来。然而,只要稍微仔细研究一下上面的代码,就会发现BoxObserver或OCBox中唯一需要留意是否使用BoxObservable的地方就是创建Observable对象的时候——从那时开始,所有东西都会使用基本的Observable接口。这意味着以后若想更改通知方式,可以继承其他Observable类,并在运行期间交换它们。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索对象
, 视图
, color
, public
, 一个
observable
observer、java observer模式、android observer模式、c# observer模式、观察者模式,以便于您获取更多的相关知识。

时间: 2024-09-30 12:51:02

observer模式的相关文章

Observer模式深度探索

server [简介]微软顶级技术大师Jeffrey Richter的作品,一向是不容错过的.为了帮助开发者这篇专论Observer模式的文章也不例外.Observer模式是经典设计模式中应用最为广泛也最为灵活多变的模式之一.本文在.NET技术框架下深入发掘了Observer模式的内涵,值得细细品味. 虽然设计模式并不是万能丹,但确实是一个非常强大的工具,开发人员或架构师可使用它积极地参与任何项目.设计模式可确保通过熟知和公认的解决方案解决常见问题.模式存在的事实基础在于:大多数问题,可能已经有

设计模式的解析和实现(C++)之十五-Observer模式

作用: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. UML结构图: 解析: Observer模式定义的是一种一对多的关系,这里的一就是图中的Subject类,而多则是Obesrver类,当Subject类的状态发生变化的时候通知与之对应的Obesrver类们也去相应的更新状态,同时支持动态的添加和删除Observer对象的功能.Obesrver模式的实现要点是,第一一般subject类都是采用链表等容器来存放Observer对象,第二

设计模式之观察者(Observer)模式与其C++通用实现(下)

我们在<设计模式之观察者(Observer)模式与其C++通用实现(中)>一文中给出了一个以C++语言实现的通用观察者模式方案骨架.然而,实际的工程项目需求往往要比理想状态复杂得多,此篇便是与读者一起探讨在现实世界中可能遇到的各种棘手问题及解决方案. 我把目前为止我所遇到的问题罗列如下: 复合主题 多线程 更新方法修改观察者链表 接下来我们一一给予讨论. (一)复合主题 考虑GUI的组件设计,我习惯用Widget类代表之,它需要处理许多用户交互以及系统事件,其中最常见的用户交互事件有鼠标及键盘

Java设计模式之Observer模式

Observer模式也叫观察者模式,是由GoF提出的23种软件设计模式的一种.Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态. 本文介绍设计模式中的(Observer)模式的概念,用法,以及实际应用中怎么样使用Observer模式进行开发. Observer模式的概念 Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态. Observer模式提供给关联对象一种同

利用Observer模式实现组件间通信

1.问题的提出 以前做一个界面的时候常常会遇到这样的尴尬情况:希望保留各个独立的组件(类),但又希望它们之间能够相互通信.譬如Windows中的Explorer,我们希望鼠标点击左边是树型目录的一个节点,右边的文件浏览能及时列出该节点目录下的文件和子目录,类似这样一个简单的应用,如果只有一个类继承JFrame,而树型组件和浏览文件的面板作为成员,就像: public class MainFrame extends JFrame { JPanel treePanel; JTree tree; JP

在J2EE中实现Observer模式

引言: 设计模式是经验的文档化.它是对被用来在特定场景下解决一般设计问题的类和相互通信 的对象的描述.更通俗的来说,它是一个问题/解决方案对.一旦我们掌握了设计模式,就等 于拥有了一支强有力的专家队伍.它甚至能够使面向对象的新手利用前人的经验找出职责明 确的类和对象,从而获得优雅的解决方案.由于设计模式也是重构的目标,如果在设计的初 期适当地引入设计模式,可以减少重构的工作量. 但是,我们也不能陷入模式的陷阱,为了使用模式而去套模式,那样会陷入形式主义.我 们在使用模式的时候,一定要注意模式的意

NET框架中的 Observer 模式

应用场景:net 框架下的HttpModule (.net2.0 代码)          先看一下 Observer 模式结构图:       再看一下.net框架中的应用结构图     关于HttpApplication.InitModules()函数的调用代码如下   1private void InitModules()2{3    //根据CONFIG文件中的配置来进行相关Module的创建并返回集合4    this._moduleCollection = RuntimeConfig

Java Q&amp;amp;A: 使用Observer模式(转)

Java Q&A: 使用Observer模式A:我想在自己的Java程序中使用Observer模式.基于此,能否提供某些示例代码来演示如何去做?Q:正如面向对象编程有助于代码复用一样,设计模式可以促进设计复用.确实,设计模式可以让你复用那些正确的.成熟的设计.但近来,批评设计模式的声音越来越多.批评者指出,缺乏经验的开发者会很容易地掉进 "模式陷阱" 之中.模式陷阱让缺乏经验的开发者迷失了方向.因而,他们在处理问题时不是去寻找可能存在的最好方案,而把最终目标集中在尽可能地实现更

Java设计模式之观察者模式(Observer模式)介绍_java

Java深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循一定的编程模式,才能使自己的代码便于理解,易于交流,Observer(观察者)模式是比较常用的一个模式,尤其在界面设计中应用广泛,而本教程所关注的是Java在电子商务系统中应用,因此想从电子商务实例中分析Observer的应用. 虽然网上商店形式多样,每个站点有自己的特色,但也有其一般的共性,单就"