观察者模式是对象的行为模式。又叫做发布-订阅模式、模型-视图模式、源-监听器模式。

抽象主题角色:主题角色将所有对观察者对象的引用到保存在一个集合里,每个主题都可以拥有任意数量的观察者。抽象主题提供一个接口,可以增加或者删除观察者对象。主题角色又叫被观察者。

具体主题角色:将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色是抽象主题的一个具体子类实现。

抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知的时候更新自己。

具体观察者角色:抽象观察者的具体子类实现。

代码

抽象主题

  1. package com.demo.exercise.observer;
  2.  
  3. /**
  4. * 抽象主题
  5. */
  6. public interface Subject {
  7.  
  8. void add(Observer observer);
  9.  
  10. void del(Observer observer);
  11.  
  12. void notifyObservers();
  13.  
  14. }

抽象观察者

  1. package com.demo.exercise.observer;
  2.  
  3. /**
  4. * 抽象观察者
  5. */
  6. public interface Observer {
  7.  
  8. void update();
  9.  
  10. }

具体观察者

  1. package com.demo.exercise.observer;
  2.  
  3. /**
  4. * 具体观察者
  5. */
  6. public class ConcreteObserver implements Observer {
  7. @Override
  8. public void update() {
  9. System.out.println(this + ":接收到通知了...");
  10. }
  11. }

具体主题

  1. package com.demo.exercise.observer;
  2.  
  3. import java.util.Iterator;
  4. import java.util.Vector;
  5.  
  6. /**
  7. * 具体主题
  8. */
  9. public class ConcreteSubject implements Subject {
  10.  
  11. private Vector<Observer> observers = new Vector<>();
  12.  
  13. @Override
  14. public void add(Observer observer) {
  15. observers.add(observer);
  16. }
  17.  
  18. @Override
  19. public void del(Observer observer) {
  20. observers.remove(observer);
  21. }
  22.  
  23. @Override
  24. public void notifyObservers() {
  25. System.out.println("通知所有观察者...");
  26. Iterator<Observer> iterator = observers.iterator();
  27. while (iterator.hasNext()){
  28. iterator.next().update();
  29. }
  30. }
  31. }

运行

  1. public static void main(String[] args) {
  2. Observer a = new ConcreteObserver();
  3. Observer b = new ConcreteObserver();
  4. Subject subject = new ConcreteSubject();
  5. subject.add(a);
  6. subject.add(b);
  7. subject.notifyObservers();
  8. }

输出

优化方案

上面的【抽象主题角色】,其中管理集合的方法,都是由子类来实现的,而实际情况则是这些管理集合的方法是所有实现子类共用的,所以可以把这些转移到抽象主题中去。

抽象主题(这里还是用的interface,你也可以用abstract class)

  1. package com.demo.exercise.observer;
  2.  
  3. import java.util.Iterator;
  4. import java.util.Vector;
  5.  
  6. /**
  7. * 抽象主题
  8. */
  9. public interface Subject {
  10.  
  11. Vector<Observer> observers = new Vector<>();
  12.  
  13. default void add(Observer observer){
  14. observers.add(observer);
  15. }
  16.  
  17. default void del(Observer observer){
  18. observers.remove(observer);
  19. }
  20.  
  21. default void notifyObservers(){
  22. System.out.println("通知所有观察者...");
  23. Iterator<Observer> iterator = observers.iterator();
  24. while (iterator.hasNext()){
  25. iterator.next().update();
  26. }
  27. }
  28.  
  29. /**
  30. * 子类需要自定义的方法
  31. * @param status
  32. */
  33. void change(String status);
  34. }

具体子类

  1. package com.demo.exercise.observer;
  2. /**
  3. * 具体主题
  4. */
  5. public class ConcreteSubject implements Subject {
  6.  
  7. private String status;
  8.  
  9. /**
  10. * 主题状态改变,调用通知方法
  11. * @param status
  12. */
  13. public void change(String status){
  14. System.out.println(status);
  15. this.status = status;
  16. this.notifyObservers();
  17. }
  18. }

运行

  1. public static void main(String[] args) {
  2. Observer a = new ConcreteObserver();
  3. Observer b = new ConcreteObserver();
  4. Subject subject = new ConcreteSubject();
  5. subject.add(a);
  6. subject.add(b);
  7. subject.change("主题状态改变");
  8. }

输出

引申

那么这种设计模式用来解决什么问题呢?类似于下面这种代码,大家初学Java的时候肯定用过,点击按钮事件,只要点击按钮,就会自动执行相关方法。

  1. JButton button = new JButton();
  2. button.addActionListener((event) -> {
  3. // TODO
  4. });

其中的原理也是观察者模式。下面我就来简单模拟一下

抽象主题

  1. package com.demo.exercise.observer;
  2.  
  3. import java.util.Iterator;
  4. import java.util.Vector;
  5.  
  6. /**
  7. * 抽象主题
  8. */
  9. public abstract class Button {
  10.  
  11. private Vector<ActionListener> observers = new Vector<>();
  12.  
  13. void addActionListener(ActionListener observer){
  14. observers.add(observer);
  15. }
  16.  
  17. void removeActionListener(ActionListener observer){
  18. observers.remove(observer);
  19. }
  20.  
  21. void notifyObservers(){
  22. Iterator<ActionListener> iterator = observers.iterator();
  23. while (iterator.hasNext()){
  24. iterator.next().actionPerformed();
  25. }
  26. }
  27. }

抽象观察者

  1. package com.demo.exercise.observer;
  2.  
  3. /**
  4. * 抽象观察者
  5. */
  6. public interface ActionListener {
  7.  
  8. void actionPerformed();
  9.  
  10. }

具体主题

  1. package com.demo.exercise.observer;
  2.  
  3. /**
  4. * 具体主题
  5. */
  6. public class JButton extends Button {
  7.  
  8. /**
  9. * 点击事件
  10. */
  11. public void click(){
  12. System.out.println("【假装产生了点击事件】");
  13. this.notifyObservers();
  14. }
  15.  
  16. }

运行

  1. public static void main(String[] args) {
  2. JButton button = new JButton();
  3. button.addActionListener(() -> {
  4. System.out.println("点击事件处理...");
  5. });
  6. button.addActionListener(() -> {
  7. System.out.println("另外一个点击事件处理...");
  8. });
  9. button.click();
  10. }

输出

Java对观察者模式的支持

一个是被观察者:java.util.Observable

一个是观察者:java.util.Observer

Observer里面只有一个update方法。

  1. public interface Observer {
  2. /**
  3. * This method is called whenever the observed object is changed. An
  4. * application calls an <tt>Observable</tt> object's
  5. * <code>notifyObservers</code> method to have all the object's
  6. * observers notified of the change.
  7. *
  8. * @param o the observable object.
  9. * @param arg an argument passed to the <code>notifyObservers</code>
  10. * method.
  11. */
  12. void update(Observable o, Object arg);
  13. }

当被观察者的状态发生改变,就会调用这一方法。

  1. public void notifyObservers(Object arg) {
  2. /*
  3. * a temporary array buffer, used as a snapshot of the state of
  4. * current Observers.
  5. */
  6. Object[] arrLocal;
  7.  
  8. synchronized (this) {
  9. /* We don't want the Observer doing callbacks into
  10. * arbitrary code while holding its own Monitor.
  11. * The code where we extract each Observable from
  12. * the Vector and store the state of the Observer
  13. * needs synchronization, but notifying observers
  14. * does not (should not). The worst result of any
  15. * potential race-condition here is that:
  16. * 1) a newly-added Observer will miss a
  17. * notification in progress
  18. * 2) a recently unregistered Observer will be
  19. * wrongly notified when it doesn't care
  20. */
  21. if (!changed)
  22. return;
  23. arrLocal = obs.toArray();
  24. clearChanged();
  25. }
  26.  
  27. for (int i = arrLocal.length-1; i>=0; i--)
  28. ((Observer)arrLocal[i]).update(this, arg);
  29. }

用法呢,我再给你示范一下。

创建一个事件对象

  1. package com.demo.exercise.observer;
  2.  
  3. /**
  4. * 事件对象
  5. */
  6. public class ClickEvent {
  7.  
  8. private String source;
  9.  
  10. public ClickEvent(String source) {
  11. this.source = source;
  12. }
  13.  
  14. public String getSource() {
  15. return source;
  16. }
  17.  
  18. public void setSource(String source) {
  19. this.source = source;
  20. }
  21. }
  1. package com.demo.exercise.observer;
  2.  
  3. import java.util.Observable;
  4. import java.util.Observer;
  5.  
  6. /**
  7. * 具体观察者
  8. */
  9. public class JJButton extends Observable {
  10.  
  11. public void click(){
  12. // 事件对象
  13. ClickEvent clickEvent = new ClickEvent("点击事件");
  14. // changed 置为true,表示状态改变,才会通知所有观察者,与之对应的是clearChanged
  15. this.setChanged();
  16. // 通知所有观察者
  17. this.notifyObservers(clickEvent);
  18. }
  19.  
  20. public void addListener(Observer o){
  21. this.addObserver(o);
  22. }
  23.  
  24. }

运行

  1. public static void main(String[] args) {
  2. JJButton button = new JJButton();
  3. button.addListener((o, arg) -> {
  4. ClickEvent event = (ClickEvent) arg;
  5. System.out.println("事件源:" + event.getSource());
  6. });
  7. button.click();
  8. }

输出

Java设计模式--观察者模式到监听器的更多相关文章

  1. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  2. 【设计模式】Java设计模式 - 观察者模式

    [设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...

  3. JAVA 设计模式 观察者模式

    用途 观察者模式 (Observer) 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观 ...

  4. Java设计模式の观察者模式(推拉模型)

    目录: 一.观察者定义 二.观察者模式的结构(推模式实现) 三.推模型和拉模型(拉模式实现) 四.JAVA提供的对观察者模式的支持 五.使用JAVA对观察者模式的支持(自带推模式实现实例) 一.观察者 ...

  5. java设计模式--观察者模式和事件监听器模式

    观察者模式 观察者模式又称为订阅—发布模式,在此模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现.此种模式通常被用来事件 ...

  6. java设计模式-观察者模式学习

    最近学习了设计模式中的观察者模式,在这里记录下学习成果. 观察者模式,个人理解:就是一个一对多模型,一个主体做了事情,其余多个主体都可以观察到.只不过这个主体可以决定谁去观察他,以及做什么事情可以给别 ...

  7. Java设计模式——观察者模式(事件监听)

    最近在看Tomcat和Spring的源码,在启动的时候注册了各种Listener,事件触发的时候就执行,这里就用到了设计模式中的观察者模式. 引-GUI中的事件监听 想想以前在学Java的GUI编程的 ...

  8. Java设计模式 - 观察者模式

    定义 观察者模式属于对象行为型模式. 在对象之间定义一对多的依赖,这样一来当一个对象改变状态,依赖它的对象都会收到通知并自动更新. 优点 1.  主题和观察者之间抽象耦合.无论什么对象主要实现了特定的 ...

  9. 我的Java设计模式-观察者模式

    相信大家都有看过<喜洋洋与灰太狼>,说的是灰太狼和羊族的"斗争",而每次的结果都是灰太狼一飞冲天,伴随着一句"我还会回来的......".为灰太狼感 ...

随机推荐

  1. 对ABBYY FineReader功能的探究

    ABBYY FineReader,一个强大的PDF阅读器和OCR识别器! 阅读主界面 OCR主界面 资源就不贴了,不过提示一下大家:Google Search 懒 得 勤 快,就可以找到. 经过研究, ...

  2. LeetCode 981. Time Based Key-Value Store

    原题链接在这里:https://leetcode.com/problems/time-based-key-value-store/ 题目: Create a timebased key-value s ...

  3. linux命令之------部分细节点

    创建文件夹/文件命令以及清除模式 mkdir +文件夹名字 touch +文件名字 rm -fr 删除文件,文件夹 -f强制删除 -r是递归 查询linux下所有启动的线程: ps -ef|grep ...

  4. shell 小数比较大小

    a=1.6b=6.1c=`echo "$a > $b" | bc`然後,如果 $c 是 1 ,那就成立,否則不成立. 参考: http://ju.outofmemory.cn ...

  5. JQuery的Ajax标准写法

    Ajax的标准写法 $.ajax({ url:"http://www.xxx",//请求的url地址 dataType:"json",//返回的格式为json ...

  6. VS Code中python代码自动格式化 代码自动检查

    VS Code菜单栏中依次打开 File—Preferences—Settings,搜索框中搜索“python.formatting.provider”, 然后在下拉菜单中选择autopep8,yap ...

  7. Schema注册表客户端

    Schema注册表客户端 与模式注册表服务器交互的客户端抽象是SchemaRegistryClient接口,具有以下结构: public interface SchemaRegistryClient ...

  8. C++11原子操作与无锁编程(转)

    不讲语言特性,只从工程角度出发,个人觉得C++标准委员会在C++11中对多线程库的引入是有史以来做得最人道的一件事:今天我将就C++11多线程中的atomic原子操作展开讨论:比较互斥锁,自旋锁(sp ...

  9. 【C++】C++中的异常解析

    异常是程序在执行期间产生的问题.C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作. 异常提供了一种转移程序控制权的方式.C++ 异常处理涉及到三个关键字:try.catch.throw ...

  10. Celery 服务搭建

    整个项目工程如下 __init__.py """ 注意点:python3.7 需要执行 pip install --upgrade https://github.com/ ...