设计模式 - 观察者模式(JDK)
定义:观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
对象: 抽象主题角色:每个抽象主题角色都可以有任意数量的观察者。抽象主题提供可以增加和删除观察者角色的方法。
具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。
代码示例:
使用JDK自带的观察者模式,来写个房东通知租客要收房租的案例。
这里的抽象主题角色和抽象观察者角色都是用的JDK的Observable和Observer两个类。
具体观察者角色:
A租客
package com.observer; import java.util.Observable;
import java.util.Observer; public class TenantA implements Observer { @Override
public void update(Observable o, Object arg) {
System.out.println("收房租了");
} }
B租客
package com.observer; import java.util.Observable;
import java.util.Observer; public class TenantB implements Observer { @Override
public void update(Observable o, Object arg) {
System.out.println("收房租了");
} }
C租客
package com.observer; import java.util.Observable;
import java.util.Observer; public class TenantC implements Observer { @Override
public void update(Observable o, Object arg) {
System.out.println("收房租了");
} }
具体主题角色:
房东
package com.observable;
import java.util.Observable;
public class Landlord extends Observable{
public void receiveRent(){
setChanged();
notifyObservers();
}
}
测试观察者模式:
package com.observable; import com.observer.TenantA;
import com.observer.TenantB;
import com.observer.TenantC; public class TestObserver { public static void main(String[] args) {
Landlord landlord = new Landlord(); TenantA tenantA = new TenantA();
TenantB tenantB = new TenantB();
TenantC tenantC = new TenantC();
landlord.addObserver(tenantA);
landlord.addObserver(tenantB);
landlord.addObserver(tenantC);
landlord.receiveRent(); } }
总结:此为简单的观察者模式案例,如果想带通知参数可以notifyObservers()方法里面传参,并且也可以传具体的主题角色过去。此setChanged()方法是告诉Observable,主题要变化了,
要通知观察者了,如果此方法没写,则永远也通知不到观察者。
源码:
package java.util; // 抽象主题角色
public class Observable { // 用于判断是否通知观察者
private boolean changed = false; // 观察者集合
private Vector<Observer> obs; public Observable() {
obs = new Vector<>();
} // 添加观察者
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
} // 删除观察者
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
} // 通知方法,无参会调用有参的
public void notifyObservers() {
notifyObservers(null);
} // 通知方法,先通过变量changed判断是否通知,为true则循环观察者进行通知
public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
} for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
} // 删除所有观察者
public synchronized void deleteObservers() {
obs.removeAllElements();
} // 通知观察者
protected synchronized void setChanged() {
changed = true;
} // 清除通知
protected synchronized void clearChanged() {
changed = false;
} // 获取是否通知
public synchronized boolean hasChanged() {
return changed;
} // 观察者个数
public synchronized int countObservers() {
return obs.size();
}
}
设计模式 - 观察者模式(JDK)的更多相关文章
- 18. 星际争霸之php设计模式--观察者模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- linkin大话设计模式--观察者模式
linkin大话设计模式--观察者模式 观察者模式定义了对象间的一对多依赖关系,让一个或者多个观察者观察一个对象主题.当主题对象的状态发生改变的时候,系统能通知所有的依赖于此对象的观察者对象,从而能自 ...
- java设计模式--观察者模式(Observer)
java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...
- 设计模式之jdk动态代理模式、责任链模式-java实现
设计模式之JDK动态代理模式.责任链模式 需求场景 当我们的代码中的类随着业务量的增大而不断增大仿佛没有尽头时,我们可以考虑使用动态代理设计模式,代理类的代码量被固定下来,不会随着业务量的增大而增大. ...
- js设计模式-观察者模式
定义: 观察者模式又叫发布订阅模式,它定义了对象间的一种一对多的依赖关系.观察者模式让两个对象松耦合地联系在一起,虽然不太清楚彼此的细节,但这不影响他们之间的互相通信. 思路 定义一个对象,在对象中实 ...
- 【设计模式】Java设计模式 - 观察者模式
[设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...
- 设计模式之 观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 本章我们讨论一个除前面的单例 ...
- 结合JDK源码看设计模式——观察者模式
前言: 现在我们生活中已经离不开微信,QQ等交流软件,这对于我们来说不仅是交流,更有在朋友圈中或空间中进行分享自己的生活,同时也可以通过这个渠道知道别人的生活.我们在看朋友圈的时候其实我们扮演的就是一 ...
- [设计模式]观察者模式1(用JDK提供的API)
观察者模式: 被观察的类: package cn.itcast.obserdemo; import java.util.Observable; //House是被观察的,这里直接继承java中的类库( ...
随机推荐
- NetBeans+Xdebug调试php代码
本文目录 : Xdebug的工作原理 Xdebug扩展的配置 NetBeans的配置 调试实例 本文小结 参考文档 Xdebug:是PHP的调试器和分析器(Debugger and Profiler ...
- html表格表单标签的结合
今天我尝试将表格表单基本标签结合起来放在网页中,发现再没用表单元素中<form></form>时各类标签功能都可显示,只是不能提交网页,所有与提交网页的标签都不能使用提交功能, ...
- Coursera 机器学习笔记(四)
主要为第六周内容机器学习应用建议以及系统设计. 下一步做什么 当训练好一个模型,预测未知数据,发现结果不如人意,该如何提高呢? 1.获得更多的训练实例 2.尝试减少特征的数量 3.尝试获得更多的特征 ...
- php面向对象1
类和对象的关系 首先看一段代码 var_dump()后的结果 注意 一个对象系统自动分配一个对象标识符!
- thinkphp5.0学习笔记(二)
本文为公司制作API接口后台的小结! 1.命名注意事项: 不要使用易混淆的名字,如index,index01... 我喜欢用拼音... 比如: public function zhuce(Reques ...
- Centos常用命令及解释
ps -ef|grep java ps:将某个进程显示出来-A 显示所有程序. -e 此参数的效果和指定"A"参数相同.-f 显示UID,PPIP,C与STIME栏位. grep命 ...
- Realm的一对多配置以及版本兼容
前言:本篇博客将介绍Realm的一些高级用法,基本使用在这里 一.配置一对多关系 // // Teacher.h #import <Realm/Realm.h> #import " ...
- Lucence
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引 ...
- 学习 ES6,一篇文章就够了
ES6 简介 ECMAScript 6 简称 ES6,是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了.它的目标是使得 JavaScript 语言可以用来编写复杂的大型应用程 ...
- Python的多线程编程
提到多线程,很多人就会望而却步,本文将由浅入深地带你攻克python多线程编程,并防止你跳入深坑, 首先看一段简单的代码: from time import ctime,sleep def play_ ...