原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6513651.html

  观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察者知道情况,其实是由目标将情况发送到观察者的。

  观察者模式多用于实现订阅功能的场景,例如微博的订阅,当我们订阅了某个人的微博账号,当这个人发布了新的消息,就会通知我们。

  现在我们举一个类似的情况,并使用代码来实现,为大家提供一个比较明显的认识。

  警察在找到嫌犯的时候,为了找到幕后主使,一般都会蹲点监察,这里我有三名便衣警察来蹲点监察2名嫌犯,三名便衣分别是:张昊天、石破天、赵日天,两名嫌犯是:大熊与黑狗,详见代码:

观察者接口:Observer

 public interface Observer {
void update(String message,String name);
}

定义三名便衣观察者:Bianyi1、Bianyi2、Bianyi3

 /**
* 便衣警察张昊天
*/
public class Bianyi1 implements Observer {
//定义姓名
private String bname = "张昊天";
@Override
public void update(String message,String name) {
System.out.println(bname+":"+name+"那里有新情况:"+ message);
}
} /**
* 便衣警察石破天
*/
public class Bianyi2 implements Observer {
//定义姓名
private String bname = "石破天";
@Override
public void update(String message,String name) {
System.out.println(bname+":"+name+"那里有新情况:"+ message);
}
} /**
* 便衣警察赵日天
*/
public class Bianyi3 implements Observer {
//定义姓名
private String bname = "赵日天";
@Override
public void update(String message,String name) {
System.out.println(bname+":"+name+"那里有新情况:"+ message);
}
}

目标接口:Huairen

 public interface Huairen {
//添加便衣观察者
void addObserver(Observer observer);
//移除便衣观察者
void removeObserver(Observer observer);
//通知观察者
void notice(String message);
}

定义两个嫌疑犯:XianFan1、XianFan2

 import java.util.*;
/**
* 嫌犯大熊
*/
public class XianFan1 implements Huairen {
//别称
private String name = "大熊";
//定义观察者集合
private List<Observer> observerList = new ArrayList<Observer>();
//增加观察者
@Override
public void addObserver(Observer observer) {
if(!observerList.contains(observer)){
observerList.add(observer);
}
}
//移除观察者
@Override
public void removeObserver(Observer observer) {
if(observerList.contains(observer)){
observerList.remove(observer);
}
}
//通知观察者
@Override
public void notice(String message) {
for(Observer observer:observerList){
observer.update(message,name);
}
}
} import java.util.*;
/**
* 嫌犯黑狗
*/
public class XianFan2 implements Huairen {
//别称
private String name = "黑狗";
//定义观察者集合
private List<Observer> observerList = new ArrayList<Observer>();
//增加观察者
@Override
public void addObserver(Observer observer) {
if(!observerList.contains(observer)){
observerList.add(observer);
}
}
//移除观察者
@Override
public void removeObserver(Observer observer) {
if(observerList.contains(observer)){
observerList.remove(observer);
}
}
//通知观察者
@Override
public void notice(String message) {
for(Observer observer:observerList){
observer.update(message,name);
}
}
}

测试类:Clienter

 public class Clienter {
public static void main(String[] args) {
//定义两个嫌犯
Huairen xf1 = new XianFan1();
Huairen xf2 = new XianFan2();
//定义三个观察便衣警察
Observer o1 = new Bianyi1();
Observer o2 = new Bianyi2();
Observer o3 = new Bianyi3();
//为嫌犯增加观察便衣
xf1.addObserver(o1);
xf1.addObserver(o2);
xf2.addObserver(o1);
xf2.addObserver(o3);
//定义嫌犯1的情况
String message1 = "又卖了一批货";
String message2 = "老大要下来视察了";
xf1.notice(message1);
xf2.notice(message2);
}
}

测试结果:

张昊天:大熊那里有新情况:又卖了一批货
石破天:大熊那里有新情况:又卖了一批货
张昊天:黑狗那里有新情况:老大要下来视察了
包拯:黑狗那里有新情况:老大要下来视察了

  通过上面的实例可以很明显的看出,观察者模式的大概模型,关键是什么呢?

  关键点:

    1、针对观察者与被观察者分别定义接口,有利于分别进行扩展。

    2、重点就在被观察者的实现中:

      (1)定义观察者集合,并定义针对集合的添加、删除操作,用于增加、删除订阅者(观察者)

      (2)定义通知方法,用于将新情况通知给观察者用户(订阅者用户)

    3、观察者中需要有个接收被观察者通知的方法。

  如此而已!

  观察者模式定义的是一对多的依赖关系,一个被观察者可以拥有多个观察者,并且通过接口对观察者与被观察者进行逻辑解耦,降低二者的直接耦合。

  如此这般,想了一番之后,突然发现这种模式与桥接模式有点类似的感觉。

  桥接模式也是拥有双方,同样是使用接口(抽象类)的方式进行解耦,使双方能够无限扩展而互不影响,其实二者还是有者明显的区别:

    1、主要就是使用场景不同,桥接模式主要用于实现抽象与实现的解耦,主要目的也正是如此,为了双方的自由扩展而进行解耦,这是一种多对多的场景。观察者模式侧重于另一方面的解耦,侧重于监听方面,侧重于一对多的情况,侧重于一方发生情况,多方能获得这个情况的场景。

    2、另一方面就是编码方面的不同,在观察者模式中存在许多独有的内容,如观察者集合的操作,通知的发送与接收,而在桥接模式中只是简单的接口引用。


同系列文章:

Java设计模式之《观察者模式》及应用场景的更多相关文章

  1. java设计模式之组合模式

    组合模式 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性.掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 & ...

  2. Java设计模式应用——组合模式

    组合模式实际上是一种树形数据结构.以windows目录系统举例,怎么样用java语言描述一个文件夹? 定义一个文件夹类,文件夹类中包含若干个子文件类和若干个文件类. 进一步抽象,把文件夹和文件都看做节 ...

  3. java设计模式5.组合模式、门面模式、享元模式、桥接模式

    组合模式 在面向对象的语言中,树结构有着巨大的威力,一个基于继承的类型的等级结构便是一个数结构,一个基于合成的对象结构也是一个数结构.组合模式将部分与整体的关系用树结构表示出来,使得客户端把一个个单独 ...

  4. JAVA设计模式之组合模式(composite)

    组合模式:树状结构专用模式 代码如下: package com.srr.dp.composite; import java.util.ArrayList; import java.util.List; ...

  5. 老和尚给小和尚讲故事引发了Java设计模式:组合模式

    目录 示例 组合模式 定义 意图 主要解决问题 优缺点 安全式和透明式的组合模式 安全式的合成模式的结构 透明式的合成模式的结构 老和尚和小和尚的故事 示例 有一个绘图系统,可以描绘各种图形,假设现在 ...

  6. Java设计模式之模板模式及使用场景

    模板模式,顾名思义,就是通过模板拓印的方式. 定义模板,就是定义框架.结构.原型.定义一个我们共同遵守的约定. 定义了模板,我们的剩余工作就是对其进行充实.丰润,完善它的不足之处. 定义模板采用抽象类 ...

  7. Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景

    我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...

  8. Java设计模式——装饰者模式

    JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...

  9. JAVA设计模式--装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...

  10. 折腾Java设计模式之访问者模式

    博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...

随机推荐

  1. vdi、vhd、vmdk虚拟格式转换

    VirtualBox带来VBoxManager.exe,可以来转换格式. 命令如下(Windows环境,Linux版的应该也有VBoxManager这个二进制文件): VBoxManager存在于Vi ...

  2. 汇编语言实现led灯的跑马灯

    led实验1.看原理图 看设备工作的原理(可能需要阅读芯片手册),看设备与cpu的连接关系 GPIO具有输入输出功能.输入:cpu想知道io引脚是高电平还是低电平那么就是输入方式输出:cpu想控制io ...

  3. Intellij idea 15配置tomcat,maven

    刚导了个项目进去,想把项目运行起开,怎么也找不到tomcat... ctrl + alt +s,打开设置窗,搜索 Application Server Tomcat: 点中间绿色的“+”号,添加选择t ...

  4. Android中关闭应用的三种方式

    当应用不再使用的时候,通常需要关闭应用,我们可以使用三种方式关闭android应用: 第一种方式:首先获取当前进程的id,然后杀死该进程(推荐) android.os.Process.killProc ...

  5. php模式设计之 中介者模式

    中介者模式 中介者模式用于开发一个对象,这个对象能够在类似对象相互之间不直接相互的情况下传送或者调解对这些对象的集合的修改.一般处理具有类似属性,需要保持同步的非耦合对象时,最佳的做法就是中介者模式. ...

  6. 2.3. 实体(Core Data 应用程序实践指南)

    Entity 实体,就像是数据表的映射类.用实体就可以创建托管对象了. 实体需要做的就是设置实体名称.实体属性及属性数据类型. 还可以根据实体配置NSManagedObject的子类(可选),创建子类 ...

  7. Hdu-2112 HDU Today (单源多点最短路——Dijsktra算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2112 题目大意:给你N个公交车站,起点,终点,各站之间的距离,求起点到终点之间的最短距离.(起点终点相 ...

  8. AdapterViewFlipper的功能和用法

    AdapterView继承了AdapterViewAnimator,它也会显示Adapter提供的多个View组件,但每次只能显示一个View组件,程序可通过showPrevious和showNext ...

  9. es6笔记5^_^set、map、iterator

    一.set 1.基本用法 数据结构Set类似于数组,但是成员的值都是唯一的,没有重复的值. let s = new Set(); [2,3,5,4,5,2,2].map(x => s.add(x ...

  10. CodeForces 721B

    B. Passwords time limit per test:2 seconds memory limit per test:256 megabytes input:standard input ...