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 并发之基础:首先全局的了解并发的知识体系,同时了解 ...
随机推荐
- numpy 基本使用1
Numpy是一个非常强大的库,具有大量线性代数以及大规模科学计算的方法. #-*- coding:utf-8 -*- import numpy as np #Numpy生成一维数组 a=np.arra ...
- Linux文件目录管理
Linux文件目录管理 文件的路径 路径: . 表示当此层目录 .. 表示上一层目录 - 代表前一个工作目录 ~ 代表"目前用户身份"所在的文件夹 ~account 代表accou ...
- 【树】Construct Binary Tree from Inorder and Postorder Traversal
题目: Given inorder and postorder traversal of a tree, construct the binary tree. 思路: 后序序列的最后一个元素就是树根, ...
- Android PdfViewer
今天按项目要求找了一个android的PDF控件,各种操作效果都非常好,在这里和大家分享一下. 这是github的地址:https://github.com/barteksc/AndroidPdfVi ...
- jdk1.8以前不建议使用其自带的Base64来加解密
JDK1.8之前的base64是内部测试使用的代码,不建议生产环境使用,而且未来可能会移除, JDK1.8提供最新可以正式使用的Base64类, 不要使用JDK中自带的sun.misc.BASE64D ...
- jieba分词过程
jieba分词最重要的就是字典,我们一般用jieba的话是用的它通用的字典,这样在特定的环境中无法分成我们想要的效果,我们需要根据我们自己的生产环境自己添加我们的字典,然后下载jieba源码进行更改, ...
- 个人总结(Alpha阶段)
Alpha总结 我们在alpha 结束之后, 每位写一个博客, 回顾并总结自己的alpha 过程,哪些方面做的好的,哪些方面做得不足需要改进的 提出问题 同时,大家一定会在过程中产生了很多问题, 结合 ...
- 记录自己使用到的git命令行代码与git使用流程
1.安装创建版本库 新建一个文件夹,用命令行实现: $ cd /d //进入d盘 $ mkdir gitproject //新建gitproject文件夹 $ cd ...
- PowerDesigner设置默认值名称规则
一.需求背景: 使用PowerDesigner创建表时,若设置某列默认值时,自动生成规则的默认值名称.比如说:DF_表名_列名 二.设置步骤: 1.选择Database—>Edit Curren ...
- 【转】Navicat Premium 12破解方法
来源网址:https://www.jianshu.com/p/42a33b0dda9c 1.按步骤安装Navicat Premium,如果没有可以去官网下载:http://www.navicat.co ...