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 并发之基础:首先全局的了解并发的知识体系,同时了解 ...
随机推荐
- python中map()函数
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回. map()是 Python 内 ...
- Spring Security构建Rest服务-1100-单机Session管理
Session失效时间: springboot配置session失效时间,只需要在application.properties里配置 #session超时时间,低于60秒按60秒server.sess ...
- oracle_jdbc_insert_into
package com.ayang.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.S ...
- jenkins自动部署tomcat
关于部署的3种思路: 远程部署(jenkins编译部署到远程服务器): 安装ssh插件 ssh插件配置 添加远程jenkins服务器节点: 本地部署(与jenkins在同一服务器): 关于maven构 ...
- Windows下如何正确下载并安装可视化的Redis数据库管理工具(redis-desktop-manager)(图文详解)
不多说,直接上干货! Redis Desktop Manager是一个可视化的Redis数据库管理工具,使用非常简单. 官网下载:https://redisdesktop.com/down ...
- JavaScript -- 猜数、遍历
----- 004-猜数.html ----- <!DOCTYPE html> <html> <head> <meta http-equiv="Co ...
- 使用exe4j将java项目打成exe执行程序
最近用Java写了一个小工具,想将它达成exe执行文件,到时候直接放某个目录下,一执行就能跑啦. 用到的工具: 1.写好的项目:可以是java项目,也可以是java web项目 2.能够打jar的工具 ...
- tomcat启动(六)Catalina分析-StandardServer.start()
从链接 Tomcat中组件的生命周期管理公共接口Lifecycle 可以知道调用的是StandardServer.startInternal() @Override protected void st ...
- Ceph 存储集群 - 搭建存储集群
目录 一.准备机器 二.ceph节点安装 三.搭建集群 四.扩展集群(扩容) 一.准备机器 本文描述如何在 CentOS 7 下搭建 Ceph 存储集群(STORAGE CLUSTER). 一共4 ...
- PM2怎么开启ES6?
node版本v6.14.2,无论是用配置文件 { "apps": [{ "name": "server", "script&quo ...