从某种角度来说,我们总是处于两种生活状态:观察者与被观察者。当处于观察者状态时,被观察的对象会向我们发出某种信息,使我们产生某种心理活动或行为状态的改变。当我们处于被观察者状态时,我们的行为活动又可以以信息的方式影响观察者。(大多数情况下是两种状态并存。) 
        作为一种面向对象的编程语言,java中的设计模式跟我们的生活模式十分相似,观察者模式也不例外。 
一    观察者模式定义与组成 
        观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让他们能够自动更新自己 。主要分为四部分:1.抽象主题角色 2.抽象观察者角色 3.具体主题角色 4.具体观察者角色 
二    自定义观察者模式

Java代码  
  1. /**抽象主题角色:
  2. * 把所有对观察者对象的引用保存在一个集合中,
  3. * 每个抽象主题角色都可以有任意数量的观察者。
  4. * 抽象主题提供一个接口,可以增加和删除观察者角色。
  5. * 一般用一个抽象类或接口来实现
  6. */
  7. public interface BeWatched {
  8. //增加一个观察者
  9. public void addWatcher(Watcher watcher);
  10. //删除一个观察者
  11. public void removeWatcher(Watcher watcher);
  12. //通知所有的观察者
  13. public void notifyWatchers(String str);
  14. }
Java代码  
  1. /**
  2. * 抽象观察者角色:为所有观察者定义一个接口,在接到主题角色的通知时更新自己
  3. * @author Administrator
  4. *
  5. */
  6. public interface Watcher {
  7. //更新自己
  8. public void update(String str);
  9. }
Java代码  
  1. /**
  2. * 具体主题角色:
  3. * 实现抽象主题角色
  4. * @author Administrator
  5. *
  6. */
  7. public class ConcreteWatched implements BeWatched{
  8. //创建一个队列来存储一个或多个观察者
  9. private ArrayList<Watcher> al= new ArrayList<Watcher>();
  10. @Override
  11. public void addWatcher(Watcher watcher) {
  12. al.add(watcher);//添加观察者到指定队列中
  13. }
  14. @Override
  15. public void removeWatcher(Watcher watcher) {
  16. al.remove(watcher);//从队列中删除观察者
  17. }
  18. @Override
  19. public void notifyWatchers(String str) {
  20. //遍历队列
  21. for(int i=0;i<al.size();i++){
  22. Watcher watcher = al.get(i);//获取队列中的观察者对象
  23. watcher.update(str);//调用它的update()方法
  24. }
  25. }
  26. }
Java代码  
  1. /**
  2. * 具体的观察者角色:
  3. * 实现抽象观察者角色
  4. * @author Administrator
  5. *
  6. */
  7. public class ConcreteWatcher implements Watcher{
  8. @Override
  9. public void update(String str) {
  10. System.out.println("已经收到通知:"+str);
  11. }
  12. }
Java代码  
  1. /**
  2. * 测试类
  3. * @author Administrator
  4. *
  5. */
  6. public class ClientTest {
  7. public static void main(String[] args){
  8. //创建被观察者对象
  9. ConcreteWatched watched = new ConcreteWatched();
  10. //创建观察者
  11. ConcreteWatcher watcher1 = new ConcreteWatcher();
  12. ConcreteWatcher watcher2 = new ConcreteWatcher();
  13. ConcreteWatcher watcher3 = new ConcreteWatcher();
  14. //添加多个观察者
  15. watched.addWatcher(watcher1);
  16. watched.addWatcher(watcher2);
  17. watched.addWatcher(watcher3);
  18. //通知观察者
  19. watched.notifyWatchers("你好!");
  20. //分割
  21. System.out.println("--------------------------------");
  22. //删除一个观察者
  23. watched.removeWatcher(watcher1);
  24. //再次通知观察者
  25. watched.notifyWatchers("很好!");
  26. }
  27. }

程序执行结果:

Java代码  
  1. 已经收到通知:你好!
  2. 已经收到通知:你好!
  3. 已经收到通知:你好!
  4. --------------------------------
  5. 已经收到通知:很好!
  6. 已经收到通知:很好!

三    对于java中的观察者模式 
        java中的内置观察者模式有两个类:一个是observable被观察者类,一个是observer观察者接口。大体上与自定义模式相同,我们编写程序时只需继承obervable类,具体实现observer接口就可以了。 
        值得注意的是:调用notifyObservers()方法之前,必须先调用setChanged()方法。这是因为observable类中把changed变量初始化为false,notifyObservers()方法会先检查该变量是否为true,如果不为ture,就不会调用update()方法,这就要我们调用notifyObservers()之前,先用setChanged()方法将changed变量设置为true。

Java代码  
  1. import java.util.Observable;
  2. import java.util.Observer;
  3. class Observe extends Observable {
  4. // 程序的入口
  5. public static void main(String args[]) {
  6. Observe watched = new Observe();// 创建被观察对象
  7. FirstObserver watch = new FirstObserver();// 创建观察者对象(可以创建多个)
  8. watched.addObserver(watch);
  9. watched.toWatchers("你好!");
  10. }
  11. // 通知观察者的方法
  12. public void toWatchers(String str) {
  13. this.setChanged();// 被观察者发生变化,把changed设置为true
  14. this.notifyObservers(str);// 通知观察者
  15. }
  16. }
  17. class FirstObserver implements Observer {
  18. // 重写更新方法
  19. public void update(Observable o, Object arg) {
  20. System.out.println("被观察者发生变化,观察者已收到通知:"+arg);
  21. }
  22. }
Java代码  
  1. 被观察者发生变化,观察者已收到通知:你好!

四    浅析监听器的工作原理 
        刚开始接触监听器的时候,很是不理解为什么我点击按钮(触发事件)监听器会自动运行,而且每当我应用监听器处理事件的时候,就会困惑不已。学完观察者模式之后,渐渐的对这个问题有了一个清晰地认识——首先,创建监听器对象(具体观察者对象),然后将监听器添加到事件源(具体主题角色)上,最后事件源变化触发事件(具体主题角色状态改变,通知观察者)!其实就是观察者模式的实现。

转载于:https://www.cnblogs.com/since1499/p/3501916.html

观察者模式(浅谈监听器工作原理)相关推荐

  1. 浅谈搜索引擎工作原理

    做为网页开发者,仅仅会编写代码完成业务功能是远远不够的,你做的网站最后需要搜索引擎这个公共入口来呈现给用户.所以搜索引擎优化是及其重要的,而要了解如何优化自己的网站从而适应搜索引擎,我们需要先了解搜索 ...

  2. java tomcat原理图,浅谈tomcat工作原理

    一个web服务器也叫做HTTP服务器,因为它使用HTTP协议同客户端(即浏览器)通信.一个基于Java的web服务器用到的两个重要类:java.net.Socket和java.net.ServerSo ...

  3. 浅谈代理服务器工作的原理

    浅谈代理服务器工作的原理 (1) 代理服务原理 代理服务器有很多种,大体来说有http,ftp,socks代理三种,其中又分透明代理和不透明代理.其中透明代理一般是网关,是硬件.所以这里讨论不透明代理 ...

  4. 浅谈“三层结构”原理与用意(转帖)

    浅谈"三层结构"原理与用意 序 在刚刚步入"多层结构"Web应用程序开发的时候,我阅读过几篇关于"asp.net三层结构开发"的文章.但其多 ...

  5. svc的参考文献_浅谈SVC的原理及作用

    浅谈 SVC 的原理及作用 超(特)高压运行检修公司 自贡中心 涂洪骏 摘要: 介绍了静止补偿器 (SVC) 的工作特性.基本原理.运行方式,重点针对 SVC 的作用进行了分析. 关键词 :静止补偿器 ...

  6. 浅谈Wi-Fi渗透--原理篇

    浅谈Wi-Fi渗透–原理篇 在这个手机比人多的移动时代,无线网络Wi-Fi遍布每个角落,殊不知隐藏其中的风云涌动 广义上无线网络应用类型如下,今天的文章就聚焦于 WLAN的一种无线局域网技术--Wi- ...

  7. 浅谈会话劫持原理及实践

    <监视你的一举一动> ---浅谈会话劫持原理及实践 前言 通常,大家所说的入侵,都是针对一台主机,在获得管理员权限后,就很是得意:其实,真正的入侵是占领整个内部网络.针对内部网络的攻击方法 ...

  8. 浅谈:Spring Boot原理分析,切换内置web服务器,SpringBoot监听项目(使用springboot-admin),将springboot的项目打成war包

    浅谈:Spring Boot原理分析(更多细节解释在代码注释中) 通过@EnableAutoConfiguration注解加载Springboot内置的自动初始化类(加载什么类是配置在spring.f ...

  9. 浅谈前端路由原理hash和history

    浅谈前端路由原理hash和history

最新文章

  1. 微信公众平台OAuth2.0授权
  2. 工作流引擎在视频网站架构中的应用
  3. android 9.0室内定位方案,Android GPS室内定位问题的解决方法(location为null)
  4. 整合swagger2生成Restful Api接口文档
  5. 孤立森林异常检测之入门
  6. JSP中base href=%=basePath%的作用
  7. 求任意大小矩阵的转置矩阵
  8. 关于JSON.parse()方法的使用说明
  9. Qt路径中常用字符“./”、“../”、“/”、“*”的含义
  10. 全国计算机等级考试题库二级C操作题100套(第47套)
  11. 在线安装docker
  12. 007_Web to lead
  13. cf修复服务器,CF:“卡顿”问题终于得到重视!新版本宣布修复,玩家这下开心了...
  14. STM8学习笔记---通过示波器分析串口数据
  15. linux常用文本编缉命令(strings/sed/awk/cut/uniq/sort)
  16. Windows XP SP2 重置 WinSock:netsh winsock reset catalog
  17. 两台电脑共享鼠标键盘Synergy
  18. 软件测试---------兼容性 / 安装卸载 / 易用性测试点(超详细)
  19. 小程序设置page背景图片透明度
  20. double转换成百分数

热门文章

  1. python restful风格_总结python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法
  2. ubuntu 16.04 安装samba
  3. 【OCR技术系列之五】自然场景文本检测技术综述(CTPN, SegLink, EAST)
  4. Delphi 7生成XML
  5. Mysql数据库备份和还原常用的命令
  6. Xamarin只言片语3——Xamarin.Android下支付宝(Alipay SDK)使用
  7. 关于stat命令和时间戳
  8. A few thoughts about Open Source Software
  9. Java压缩/解压缩二进制文件
  10. 轻松八句话 教会你完全搞定MySQL数据库(基础)