1.场景模式抽象

订阅报纸的过程,如果报纸来了的时间不确定,那么订报纸的人如何知道呢?可以抽象为:当一个对象的状态发生改变的时候,如何让依赖他的所有对象得到通知,并进行相应的处理呢?生活中最常见的例子就是:当你一上线,QQ后台就给你不上线的时候收到的所有的消息。

2.使用观察者模式来解决方案

2.1观察者模式定义

定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变的时候,所有依赖他的对象都得到通知并进行自动更新。

2.2观察者模式结构说明

2.3.观察者模式示例代码

package demo11.observer.example1;

import java.util.*;
/**
* 目标对象,它知道观察它的观察者,并提供注册和删除观察者的接口
*/
public class Subject {
/**
* 用来保存注册的观察者对象
*/
private List<Observer> observers = new ArrayList<Observer>();
/**
* 注册观察者对象
* @param observer 观察者对象
*/
public void attach(Observer observer) {
observers.add(observer);
}
/**
* 删除观察者对象
* @param observer 观察者对象
*/
public void detach(Observer observer) {
observers.remove(observer);
}
/**
* 通知所有注册的观察者对象
*/
protected void notifyObservers() {
for(Observer observer : observers){
observer.update(this);
}
}
}
***************************************************************************************************
package demo11.observer.example1; /**
* 具体的目标对象,负责把有关状态存入到相应的观察者对象,
* 并在自己状态发生改变时,通知各个观察者
*/
public class ConcreteSubject extends Subject {
/**
* 示意,目标对象的状态
*/
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
//状态发生了改变,通知各个观察者
this.notifyObservers();
}
}
***************************************************************************************************
package demo11.observer.example1; /**
* 观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象
*/
public interface Observer {
/**
* 更新的接口
* @param subject 传入目标对象,好获取相应的目标对象的状态
*/
public void update(Subject subject); }
***************************************************************************************************
package demo11.observer.example1; /**
* 具体观察者对象,实现更新的方法,使自身的状态和目标的状态保持一致
*/
public class ConcreteObserver implements Observer {
/**
* 示意,观者者的状态
*/
private String observerState; public void update(Subject subject) {
// 具体的更新实现
//这里可能需要更新观察者的状态,使其与目标的状态保持一致
observerState = ((ConcreteSubject)subject).getSubjectState();
}
}

3.使用观察者模式来实现示例

3.1目标对象,作为被观察者

package demo11.observer.example2;

import java.util.ArrayList;
import java.util.List; /**
* 目标对象,作为被观察者
*/
public class Subject {
/**
* 用来保存注册的观察者对象,也就是报纸的订阅者
*/
private List<Observer> readers = new ArrayList<Observer>();
/**
* 报纸的读者需要先向报社订阅,先要注册
* @param reader 报纸的读者
* @return 是否注册成功
*/
public void attach(Observer reader) {
readers.add(reader);
}
/**
* 报纸的读者可以取消订阅
* @param reader 报纸的读者
* @return 是否取消成功
*/
public void detach(Observer reader) {
readers.remove(reader);
}
/**
* 当每期报纸印刷出来后,就要迅速的主动的被送到读者的手中,
* 相当于通知读者,让他们知道
*/
protected void notifyObservers() {
for(Observer reader : readers){
reader.update(this);
}
}
}

3.2报纸对象,具体的目标实现

package demo11.observer.example2;
/**
* 报纸对象,具体的目标实现
*/
public class NewsPaper extends Subject {
/**
* 报纸的具体内容
*/
private String content; /**
* 获取报纸的具体内容
*
* @return 报纸的具体内容
*/
public String getContent() {
return content;
} /**
* 示意,设置报纸的具体内容,相当于要出版报纸了
*
* @param content
* 报纸的具体内容
*/
public void setContent(String content) {
this.content = content;
// 内容有了,说明又出报纸了,那就通知所有的读者
notifyObservers();
}
}

3.3观察者,比如报纸的读者

package demo11.observer.example2;
/**
* 观察者,比如报纸的读者
*/
public interface Observer {
/**
* 被通知的方法
* @param subject 具体的目标对象,可以获取报纸的内容
*/
public void update(Subject subject);
}

3.4真正的读者,为了简单就描述一下姓名

package demo11.observer.example2;
/**
* 真正的读者,为了简单就描述一下姓名
*/
public class Reader implements Observer{
/**
* 读者的姓名
*/
private String name; public void update(Subject subject) {
//这是采用拉的方式
System.out.println(name+"收到报纸了,阅读先。内容是==="+((NewsPaper)subject).getContent());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

3.5客户端使用

package demo11.observer.example2;

public class Client {
public static void main(String[] args) {
//创建一个报纸,作为被观察者
NewsPaper subject = new NewsPaper(); //创建阅读者,也就是观察者
Reader reader1 = new Reader();
reader1.setName("张三"); Reader reader2 = new Reader();
reader2.setName("李四"); Reader reader3 = new Reader();
reader3.setName("王五"); //注册阅读者
subject.attach(reader1);
subject.attach(reader2);
subject.attach(reader3); //要出报纸啦
subject.setContent("本期内容是观察者模式");
}
}

4.认识观察者模式

4.1目标和观察者之间的关系

典型的一对多的关系。

4.2单向依赖

观察者依赖目标,目标不依赖观察者。

4.3观察者模式的调用顺序图

4.4推模型

推模型:顾名思义,目标对象主动向观察者推送消息,不管观察者是否需要,相当于广播通信

与前面不同的地方在于

	public void update(String content) {
//这是采用推的方式
System.out.println(name+"收到报纸了,阅读先。内容是==="+content);
} /**
* 当每期报纸印刷出来后,就要迅速的主动的被送到读者的手中,
* 相当于通知读者,让他们知道
* @param content 要主动推送的内容
*/
protected void notifyObservers(String content) {
for(Observer reader : readers){
reader.update(content);
}
} /**
* 示意,设置报纸的具体内容,相当于要出版报纸了
* @param content 报纸的具体内容
*/
public void setContent(String content) {
this.content = content;
//内容有了,说明又出报纸了,那就通知所有的读者
notifyObservers(content);
}

4.5拉模型

拉模型:顾名思义,目标对象在通知观察者的时候,只传递少量信息,如果观察者需要更具体的信息,由观察者主动到目标对象去获取。

	public void update(Subject subject) {
// 这是采用拉的方式
System.out.println(name + "收到报纸了,阅读先。内容是===" + ((NewsPaper) subject).getContent());
}

4.6java中的观察者模式

java中已经定义了观察者模式,详细的可以查查。这里不再复述。基本上差不多。

5.观察者模式思考

5.1优缺点:

优点:实现了观察者和目标之间的抽象耦合,实现了动态联动,支持广播通信

缺点:可能会引起无谓的操作

5.2观察者模式的本质:

触发联动

设计模式13---设计模式之观察者模式(Observer)(行为型)的更多相关文章

  1. [Android&amp;Java]浅谈设计模式-代码篇:观察者模式Observer

    观察者,就如同一个人,对非常多东西都感兴趣,就好像音乐.电子产品.Game.股票等,这些东西的变化都能引起爱好者们的注意并时刻关注他们.在代码中.我们也有这种一种方式来设计一些好玩的思想来.今天就写个 ...

  2. 设计模式之十:观察者模式(Observer)

    观察者模式: 在对象之间定义了一种一对多的依赖关系.当一个对象改变它的状态时,全部依赖它的对象会自己主动接收通知并更新自己的状态. Define a one-to-many dependency be ...

  3. HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern)

    观察者模式:定义了对象之间一对多的依赖关系,这样一来,当一个对象的状态发生改变时,它的依赖者将会受到通知并且自动更新. 有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事,对象甚至在运行时可以 ...

  4. Headfirst设计模式的C++实现——观察者模式(Observer)

    WeatherData.h #ifndef WEATHERDATA_H_INCLUDED #define WEATHERDATA_H_INCLUDED #include <set> #in ...

  5. 观察者模式 Observer 发布订阅模式 源 监听 行为型 设计模式(二十三)

    观察者模式 Observer 意图 定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新. 别名:依赖(Dependents),发布订阅(Publish-Su ...

  6. 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)

    设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...

  7. 设计模式18:Observer 观察者模式(行为型模式)

    Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象) ...

  8. Java设计模式(20)观察者模式(Observer模式)

    Java深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循 ...

  9. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  10. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

随机推荐

  1. winzip15.0注冊码

    username:Juzhaofeng 授权码:MPZRP-Y7LWW-K1DKG-FM92E-2C5F5-ZEKFF

  2. POJ2151Check the difficulty of problems 概率DP

    概率DP,还是有点恶心的哈,这道题目真是绕,问你T个队伍.m个题目.每一个队伍做出哪道题的概率都给了.冠军队伍至少也解除n道题目,全部队伍都要出题,问你概率为多少? 一開始感觉是个二维的,然后推啊推啊 ...

  3. [RxJS] Logging a Stream with do()

    To help understand your stream, you’ll almost always want to log out some the intermediate values to ...

  4. Java八个并发学习——线程同步工具CyclicBarrier

    本文是一篇文章对网络的研究摘要,感谢您的无私分享. CyclicBarrier 类有一个整数初始值,此值表示将在同一点同步的线程数量.当当中一个线程到达确定点,它会调用await() 方法来等待其它线 ...

  5. [小技巧] 把虚拟机中的Linux系统安装到U盘中

    出于各种需求,很多用户可能经常会在Windows系统中安装虚拟机,然后在虚拟机中安装Linux系统.使用虚拟机的优点是可以同时使用多个系统,而缺点也是显然的,也就是程序运行效率较差.   而实际上,L ...

  6. python - socket练习(输入系统命令)

    socket_server端代码: #!/usr/bin/env python # -*- coding:utf-8 -*- # Auther: pangguoping import socket i ...

  7. xhtml规范

    在使用XHTML语言进行网页制作时,必须要遵循一定的语法规范.下面进行详细讲解,其中具体内容可以分为以下几点. 文档方面: 必须定义文档类型(DTD)和你的名字空间 标签方面: 所有标签均要小写,合理 ...

  8. 调试EF源码

    在解决方案中添加下载好的EF的源码的引用 在新建项目中添加程序集的引用 添加配置文件中的节点 测试 获取程序集的公钥标记: 使用sn.exe命令 使用reflector

  9. js、java传值编码

    一.请求使用post方法不需要考虑编码问题.二.前后台统一编码,支持中文,不考虑编码:tomcat utf-8编码三.前后台编码不统一 $.ajax({                url : &q ...

  10. C++内存对象布局

    本章主要介绍了c++类中成员变量.函数对象的在内存中布局. 当c++类中不包含virtual机制类的函数时,内部nostatic member被包含在每一个class object之中,就想c str ...