Java设计模式----观察者模式详解
【声明】
欢迎转载,但请保留文章原始出处→_→
生命壹号:http://www.cnblogs.com/smyhvae/
文章来源:http://www.cnblogs.com/smyhvae/p/3899208.html
【正文】
一、观察者模式的定义:
简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监听一个主题对象。这样一来,当被观察者状态发生改变时,需要通知相应的观察者,使这些观察者对象能够自动更新。例如:GUI中的事件处理机制采用的就是观察者模式。
二、观察者模式的实现:
- Subject(被观察的对象接口):规定ConcreteSubject的统一接口 ; 每个Subject可以有多个Observer;
- ConcreteSubject(具体被观察对象):维护对所有具体观察者的引用的列表 ;–状态发生变化时会发送通知给所有注册的观察者。
- Observer(观察者接口):规定ConcreteObserver的统一接口;定义了一个update()方法,在被观察对象状态改变时会被调用。
- ConcreteObserver(具体观察者):维护一个对ConcreteSubject的引用;特定状态与ConcreteSubject同步; 实现Observer接口,update()方法的作用:一旦检测到Subject有变动,就更新信息。
图表描述如下:

注:在被观察者类中需要有一个集合维护所有观察者。
三、举例说明:
【方案一】:自己定义接口或者类来实现观察者模式。
步骤如下:
(1)定义被观察者所具有的接口:
package com.vince.observer;
public interface Observable {
//注册为一个观察者
public void registerObserver(Observer observer); //取消观察者
public void removeObserver(Observer observer); //通知所有观察者更新信息
public void notifyObservers();
}
(2)定义具体的被观察者:杯子
package com.vince.observer;
import java.util.Vector; public class Cup implements Observable{
//被观察者维护的一个观察者对象列表
private Vector<Observer> vector = new Vector<Observer>();
private float price; public Cup(float price){
this.price = price;
} public float getPrice() {
return price;
}
public void setPrice(float price) {
//修改价格时,通知所有观察者
this.price = price;
notifyObservers();
}
@Override
public void registerObserver(Observer observer) {
//注册观察者
vector.add(observer);
}
@Override
public void removeObserver(Observer observer) {
//取消观察者
vector.remove(observer);
}
@Override
public void notifyObservers() {
//实现通知所有的观察者对象
for (Observer observer:vector) {
observer.update(price);
}
}
}
(3)定义观察者所具有的共同的接口:(更新数据最终当然是在观察者那里进行啦)
package com.vince.observer;
public interface Observer {
public void update(float price);
}
(4)定义具体的观察者对象:
package com.vince.observer;
public class Person implements Observer{
private String name;
public Person(String name){
this.name = name;
}
@Override
public void update(float price) {
System.out.println(name+"关注的杯子的价格已更新为:"+price);
}
}
(5)测试:
package com.vince.observer;
public class Test {
public static void main(String[] args) {
//创建一个被观察者对象
Cup doll = new Cup(3000);
//创建两个观察者对象
Person p1 = new Person("生命壹号");
Person p2 = new Person("生命贰号");
//注册成为一个观察者
doll.registerObserver(p1);
doll.registerObserver(p2); System.out.println("第一轮促销:");
doll.setPrice(2698);// 价格变动
System.out.println("第二轮促销:");
doll.setPrice(2299);//
System.out.println("第三轮促销:");
doll.setPrice(1998); doll.removeObserver(p2); //将生命二号移除
System.out.println("第四轮促销:");
doll.setPrice(1098); }
}
运行后,显示结果如下:

【方案二】:直接调用JDK的API去实现。
步骤如下:
(1) 通过继承Observable类实现具体的被观察者对象:
package com.vince.observer2;
import java.util.Observable; public class Cup extends Observable{
private float price; public Cup(float price){
this.price = price;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
15 this.setChanged();//通知,数据已改变
this.notifyObservers();
} }
(2)通过实现java.util.Observer接口实现具体的观察者对象:
package com.vince.observer2;
import java.util.Observable;
import java.util.Observer; public class Person implements Observer{
private String name;
public Person(String name){
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
if(o instanceof Cup){
Cup cup = (Cup)o;
System.out.println(name+"关注的杯子价格已更新为:"+cup.getPrice());
}
}
}
(3)测试:
package com.vince.observer2;
public class Test {
public static void main(String[] args) {
Cup cup = new Cup(3000);
Person p1 = new Person("生命壹号");
Person p2 = new Person("生命贰号");
cup.addObserver(p1);
cup.addObserver(p2);
System.out.println("第一轮促销");
cup.setPrice(2988);
System.out.println("第二轮促销");
cup.setPrice(2698); cup.deleteObserver(p2);
System.out.println("第三轮促销");
cup.setPrice(1998);
}
}
运行后,结果如下:

【工程文件】
链接:http://pan.baidu.com/s/1c03rLFM
密码:hois
四、总结:(观察者模式的作用)
- 观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表。
由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,那么这个对象必然跨越抽象化和具体化层次。
- 观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知。
推荐学习链接:http://blog.csdn.net/crave_shy/article/details/21235855
我的公众号
想学习代码之外的软技能?不妨关注我的微信公众号:生命团队(id:vitateam)。
扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:

Java设计模式----观察者模式详解的更多相关文章
- java设计模式案例详解:观察者模式
观察者模式的应用场景: 1. 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变. 2. 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节. 举个例子说明,这个例子讲 ...
- java设计模式案例详解:工厂模式
1.简单工厂模式 在不考虑扩展的情况下还是很好用的,其实我们写代码也很经常用到,其主要理解在于传入不同参数则构建不同对象,只有一个工厂,如需添加产品涉及到扩展需要修改比较多的东西,不符合开闭原则,如下 ...
- Java设计模式 - 单例模式详解(扩展)
单例模式引发相关整理 如何破坏单例模式 示例: /** * 如果破坏单例模式 * * @author sunyang * @date 2018/11/13 20:14 */ public class ...
- java设计模式案例详解:代理模式
代理模式就是用一个第三者的身份去完成工作,其实际意义跟字面意思其实是一样的,理解方式有很多,还是例子直观. 本例的实现类是实现买票功能,实际应用想要添加身份验证功能,利用代理模式添加验证步骤.上例子: ...
- Java设计模式-单例模式详解(上)
单例模式整理 敲了多年代码后,回头来看会别有一番滋味在心头.. 概念 单例模式是为了保证在一个jvm环境下,一个类仅有一个对象. 代码中常见的懒汉式.饿汉式,这些实现方式可以通过代码的设计来强制保证的 ...
- Java设计模式 - 单例模式详解(下)
单例模式引发相关整理 关联线程安全 在多线程下,懒汉式会有一定修改.当两个线程在if(null == instance)语句阻塞的时候,可能由两个线程进入创建实例,从而返回了两个对象.对此,我们可以加 ...
- 【转】Java设计模式-单例模式详解
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6510196.html 所谓单例,指的就是单实例,有且仅有一个类实例,这个单例不应该由人来控 ...
- Java Enum用法详解
Java Enum用法详解 用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举 ...
- 最强Java并发编程详解:知识点梳理,BAT面试题等
本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...
随机推荐
- 【字符串】Simplify Path(栈)
题目: Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/&quo ...
- Okhttp3上传多张图片同时传递参数
之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片. 最近做项目,打算换个方法上传图片. Android发展到现在,Okhttp显得越来越重要,所以,这次我选择用Okhttp上传图片. ...
- 如何自学计算机科学与技术(Teach Yourself Computer Science)
如果你是一个自学成才的半吊子,或者是从培训班毕业的小菜鸟.那么,你欠自己一份计算机科学的专业知识.感谢上帝,如今你可以接受世界水平的计算机教育,但无需花费数年时间和一笔不小的金钱. 互联网上的学习资源 ...
- 编写dimgr脚本学到的知识及技巧
编写dimgr是为了管理手机上的镜像,在此总结下过程中学到的知识及技巧(不讨论具体用法). 参数处理 以往处理脚本参数直接用循环加判断语句,若是脚本只有简单参数,这无疑是简便可行的方法.但当需要处理复 ...
- 从cpu负载到jstack分析线程状态
示例代码: public class CPULockTest { private static Object lock1 = new Object(); private static Object l ...
- php中接收参数,不论是来自GET还是POST方法
不多说,直接上代码, 其实也就是先用GET的方法去获取,如果值为空,在用POST方法去获取 写下来是为了方便和备忘 function getParam($str){ if ( isset( ...
- 根据模板导出excel
@RequestMapping(value = "/export", method = RequestMethod.GET) public void exportApprovals ...
- Spring Boot 使用Redis
转载自:http://www.cnblogs.com/ityouknow/p/5748830.html Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化 ...
- ARM的体系结构与编程系列博客——ARM体系变种
ARM体系变种的简介 有人会很奇怪一件事情,ARM居然会变种,不会是基因突变了吧,呵呵,其实ARM变种通俗一点来讲呢,就是ARM突然具备了一种特定的功能!并非是基因突变哦!ARM是reboot好不好? ...
- ZBar之ZBarReaderViewController
// // ViewController.m // ZBarReaderViewController // // Created by City--Online on 15/6/9. // Copyr ...