文 / vincentzh

原文连接:http://www.cnblogs.com/vincentzh/p/6031844.html

  LZ刚刚开始心热的开启了博客之路,想着记点流水账,可帝都的天都冷成狗了一样,还特么不供暖,冻的打字都感觉不到键盘在哪里。。。

目录

  1. 1、概述
  2. 2、原理
  3. 3、结构组成
  4. 4、实现
    1. 4.1 静态代理
    2. 4.2 动态代理
  5. 5、总结

1、概述

  观察者模式通俗讲就是一堆观察者对象同时观察一个对象的状态。好比一妹子后面跟了一群追求者,妹子一看,这仨还错,有才华、有相貌、有money,先允许你们三来竞争吧。姑娘口渴了,仨小伙急了,纷纷去给姑娘去买水,又是矿泉水又是饮料的。

2、原理

  观察者模式的原理比较简单,类似于监听,定义了一种一对多的关系,让多个观察者同时监听一个主题对象,当主题角色状态发生变化时,会通知所有观察者对象,使它们去自行更新。

3、结构组成

  观察者模式原理简单,但结构上还是稍微有点绕。其包含了4个角色:

抽象主题角色(Subject):抽象主题角色只提供一个接口,它将所有的观察者引用保存再一个容器里,同时提供增加观察者、删除观察者、通知所有观察者的方法;

具体主题角色(ConcreteSubject):具体主题角色提供一个容器保存所有观察者的引用,当其状态发生改变时,会通知在其容器内登记过的所有观察者;

抽象观察者角色(Observer):抽象观察者角色为具体观察者角色定义了一个接口,它提供了具体观察者角色更新自己的方法;

具体观察者角色(ConcreteObserver):具体观察者角色实现了抽象观察者角色定义的更新方法,以更新自己状态和主题角色状态一致,或着说相应主题角色状态的改变。

4、实现

  观察者模式的实现在4.1这里举了个例子,有点牵强,但能说明问题;4.2是利用JDK提供的接口和类去实现的观察者模式。

4.1 场景案例

  年关将至,镇长下乡去视察,看看下属各个村儿里今年的收入情况怎么样,群众有没有赚到钱呀,庄稼收成好不好呀,bulabula...。各村儿一听镇长要下乡,好家伙,赶紧趁这个机会好好表现表现,说不定明年镇长能多给村儿里几个低保名额。A村提前给镇长就做好了热腾腾的裤带面,B村知道领导都好面子,老早就搞起了锣鼓队给领导办欢迎仪式。

抽象观察者类:

 package com.cnblogs.vincentzh.observer;
// 抽象观察者角色(村儿接口)
public interface Villages
{
public void action(String str);
}

抽象主题类:

 package com.cnblogs.vincentzh.observer;
// 抽象主题角色(领导接口)
public interface LeaderShip
{
public boolean add(Villages village);
public boolean delete(Villages village);
public void notify(String str);
}

具体主题类:

 package com.cnblogs.vincentzh.observer;

 import java.util.HashSet;
// 具体主题角色(镇长)
public class Mayor implements LeaderShip
{
// 观察者容器
public HashSet<Villages> villages = new HashSet<Villages>(); @Override
public boolean add(Villages village)
{
return villages.add(village);
} @Override
public boolean delete(Villages village)
{
return villages.remove(village);
} @Override
public void notify(String str)
{
for(Villages village : villages)
{
village.action(str);
}
}
}

具体观察者类:

 package com.cnblogs.vincentzh.observer;
// 具体观察者角色(村儿)
public class Village implements Villages
{
private String string; public Village(String string)
{
this.string = string;
} @Override
public void action(String str)
{
System.out.println(str);
System.out.println(string + " for LeaderShip");
}
}

环境测试类:

 package com.cnblogs.vincentzh.observer;
// 环境测试类
public class Test
{
/**
* @param args
*/
public static void main(String[] args)
{
LeaderShip mayor = new Mayor(); Village village1 = new Village("village1: We cooking"); // A村做饭
Village village2 = new Village("village2: We welcome"); // B村欢迎 mayor.add(village1);
mayor.add(village2);
mayor.notify("Mayor is comming!"); System.out.println("------------------------------");
mayor.delete(village1);
mayor.notify("Mayor is comming!");
}
}

结果:

4.2 JDK实现

  JDK内部提供了用于实现观察者模式的Observable 类和 Observer 接口,它们分别充当了抽象主题角色和抽象观察者角色,要实现观察者模式,只需要定义具体主题类并继承 Observable 类重写相应的方法,同时定义具体观察者对象实现 Observer 接口并实现其中的更新方法即可。

具体主题类:

 package com.cnblogs.vincentzh.observermodel;

 import java.util.HashSet;
import java.util.Observable;
import java.util.Observer;
// 具体主题角色(及被观察者)
public class Watched extends Observable
{
// 观察者容器
private HashSet<Observer> sets = new HashSet<Observer>(); @Override
public synchronized void addObserver(Observer o)
{
sets.add(o);
} @Override
public synchronized void deleteObserver(Observer o)
{
sets.remove(o);
} @Override
public void notifyObservers()
{
for(Observer observer : sets)
{
observer.update(this, this);
}
}
}

具体观察者类:

 package com.cnblogs.vincentzh.observermodel;

 import java.util.Observable;
import java.util.Observer;
// 观察者角色(即观察者)
public class Watcher implements Observer
{
private String str; public Watcher(String str)
{
this.str = str;
} @Override
public void update(Observable o, Object arg)
{
System.out.println((String)str);
}
}

环境测试类:

 package com.cnblogs.vincentzh.observermodel;
// 环境测试类
public class Test
{
public static void main(String[] args)
{
Watcher watcher1 = new Watcher("watched1");
Watcher watcher2 = new Watcher("watched2"); Watched watched = new Watched(); watched.addObserver(watcher1);
watched.addObserver(watcher2);
watched.notifyObservers(); System.out.println("---------------------------"); watched.deleteObserver(watcher1);
watched.notifyObservers();
}
}

结果:

5、总结

  观察者模式对主题对象和观察者对象进行了解耦,使双方都依赖于抽象,而并不是依赖于对方的具体对象,使得双方各自的变化都不会影响到对方的具体对象。但双方并没有完全的独立,抽象主题通知时仍然依赖于抽象观察者。当其他多个对象需要根据一个对象的状态发生相应的改变或操作时(或类似发布/订阅模式),可使用观察者模式来解决。

设计模式-观察者模式(Observer Model)的更多相关文章

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

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

  2. 设计模式-观察者模式(Observer Pattern)

    观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...

  3. 设计模式 - 观察者模式(Observer Pattern) 详细说明

    观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  4. 设计模式 - 观察者模式(Observer Pattern) 详细解释

    观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  5. 设计模式 - 观察者模式(Observer Pattern) Java内置 用法

    观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...

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

    一.观察者模式 观察者模式是在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新.观察者模式也被称之为:主题-观察者模式,发布-订阅模式,前者是一,后者是多. ...

  7. 大话设计模式--观察者模式 Observer -- C++ 实现实例

    大话设计模式--1.观察者模式: 定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有的 观察者对象,使他们能够自动更新自己. 使用场合: 当一 ...

  8. [工作中的设计模式]观察者模式observer

    一.模式解析 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观察者模式又叫订阅发布模式, ...

  9. C#设计模式——观察者模式(Observer Pattern)1

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

  10. C#设计模式——观察者模式(Observer Pattern)

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

随机推荐

  1. crossplatfrom---electron入门教程

    1.atom/electron github: https://github.com/atom/electron 中文文档: https://github.com/atom/electron/tree ...

  2. php的函数和数组

    //php函数//1.简单函数//四要素:返回类型,函数名,参数列表,函数体/*function Show(){    echo "hello";}Show();*///2.有返回 ...

  3. MongoDB 搭建分片集群

    在MongoDB(版本 3.2.9)中,分片是指将collection分散存储到不同的Server中,每个Server只存储collection的一部分,服务分片的所有服务器组成分片集群.分片集群(S ...

  4. EF-DbUpdateException--实体类和数据库列不对应的解决方案

    错误信息 1.VS实体类里面的字段 2数据库里面的字段 猜测是因为字段数不匹配导致的 3删除多余字段 5.结果 错误信息贴上: -------------------------Log_Header- ...

  5. 【Win 10应用开发】多窗口视图

    Windows App一般情况下,同一时刻只能有一个应用程序实例在运行,为了在特殊需求下可以同时呈现不同的UI,SDK提供了多视图操作支持. 应用程序可以创建新的应用视图,以新的视图为基础可以呈现与主 ...

  6. MyEclipse 2014(激活)

    激活 破解附件包下载:http://pan.baidu.com/s/1c27Dwe0 提取密码:qy38 详细破解步骤请参考:http://blog.my-eclipse.cn/myeclipse-2 ...

  7. matlab 循环读入多个mat文件组合成一个mat文件

    今天做实验,需要到这个功能,在朋友的告知下,写了代码,在此留个标记 clc clear load('F:\效果对比\colorhist\1.mat'); a=ans; a=a'; : filename ...

  8. SQL 数据库管理---公司培训

    一.实例 一个SQL的服务引擎就是一个SQL实例,每装一次SQL就会产生一次实例. 实例分为命名实例和默认实例,一台Windows服务器可以有多个SQL实例,但是只能有一个默认实例. 不同的实例之间相 ...

  9. IOS各种集合遍历效率对比

    前言: 对于ios项目开发中总会遇见各种集合遍历,出于对各种遍历效率的好奇心,所以准备写个测试程序测试一下 首先:先声明一个NSMutableArray,测试数据量分别是1000条,10000条,10 ...

  10. JavaScript中的日期处理注意事项

    在业务逻辑比较多的系统里面,一般都会涉及到日期的处理.包括选择起始日期和结束日期,结束日期要大于起始日期,日期的显示和输入等. 输入这一块基本都是使用jQuery datetimepicker,后来系 ...