Observer模式即观察者模式,该模式中,被观察者的状态发生变化后会通知给观察者。

此模式适用于根据对象状态进行处理的场景。

示例程序

下面代码的功能是:被观察者是一个随机数生成器,有两个观察者,分别以数值形式和图示形式展示被观察者生成的数字。

程序类图

程序

抽象的数字生成器

public abstract class NumberGenerator {
//观察者列表
private ArrayList observers = new ArrayList();
//增加观察者
public void addObserver(Observer observer) {
observers.add(observer);
}
//删除观察者
public void deleteObserver(Observer observer) {
observers.remove(observer);
}
//提醒观察者
public void notifyObservers() {
Iterator it = observers.iterator();
while (it.hasNext()) {
Observer o = (Observer)it.next();
o.update(this);
}
}
public abstract int getNumber();
public abstract void execute();
}

具体的数字生成器

执行execute()方法后通知观察者

public class RandomNumberGenerator extends NumberGenerator {
private Random random = new Random();
private int number;
public int getNumber() {
return number;
}
public void execute() {
for (int i = 0; i < 20; i++) {
number = random.nextInt(50);
notifyObservers();
}
}
}

观察者接口

public interface Observer {
void update(NumberGenerator generator);
}

观察者(数字形式展示)

public class DigitObserver implements Observer {
public void update(NumberGenerator generator) {
System.out.println("DigitObserver:" + generator.getNumber());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}

观察者(图形方式展示)

public class GraphObserver implements Observer {
public void update(NumberGenerator generator) {
System.out.print("GraphObserver:");
int count = generator.getNumber();
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println("");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}

执行

public class Main {
public static void main(String[] args) {
NumberGenerator generator = new RandomNumberGenerator();
Observer observer1 = new DigitObserver();
Observer observer2 = new GraphObserver();
generator.addObserver(observer1);
generator.addObserver(observer2);
generator.execute();
}
} //结果
DigitObserver:22
GraphObserver:**********************
DigitObserver:11
GraphObserver:***********
DigitObserver:40
GraphObserver:****************************************
DigitObserver:39
GraphObserver:***************************************
DigitObserver:28
GraphObserver:****************************
DigitObserver:23
GraphObserver:***********************
DigitObserver:38
GraphObserver:**************************************
DigitObserver:39
GraphObserver:***************************************
......省略

角色和类图

角色

  • Subject:被观察者

被观察者内部维护了一个观察者的list,定义了增加和删除观察者的方法。同时还定义了一个通知观察者的方法,作用是:如果自己内部发生了变化,通知观察者取得这些变化。本例中由NumberGenerator扮演这个角色。

  • ConcreteSubject:具体的被观察者

实现了被观察者的执行方法,在执行过程中调用方法通知观察者。本例中由RandomNumberGenerator扮演此角色。

  • Observer:观察者

声明供被观察者调用的方法,此方法可以获得被观察者状态的变化值。本例中由Observer接口扮演此角色。

  • ConcreteObserver:具体的观察者

实现了观察者接口的方法,通过这个方法可以获得被观察者的值,达到监控的目的。本例中由DigitObserverGraphObserver扮演此角色。

类图

思路拓展

可复用性

对于具体的被观察者和观察者而言,他们之间的关系由他们的父类和接口进行关联。

具体的被观察者RandomNumberGenerator不需要知道观察者是谁,有多少,它只负责执行时调用通知方法通知观察者即可。

具体的观察者GraphObserverDigitObserver不需要知道是谁实现了NumberGenerator,只负责拿到值并处理即可。

这样的设计降低了耦合度,提升组件可复用性。其做法的特点是:

利用抽象类和接口从具体类中抽出抽象方法。

将实例作为参数传递至类中,或者在类的字段中保存实例时,不使用具体类型,而是使用抽象类型和接口。

Observer的顺序

如果观察者能够改变被观察者的数据,那就要注意观察者的调用顺序了。还要注意防止循环调用

当Subject发生变化时,通知Observer,Observer改变Subject,Subject发生变化,通知Observer...

MVC模式

Model发生改变时通知View,View根据Model的值显示新的内容。Model就是被观察者,View就是观察者。

最新文章

  1. Oracle分析函数入门
  2. java合并pdf
  3. Android异步任务机制之AsycTask
  4. JS实现的一个query字符串转Json格式数据的方法
  5. 密码加SALT原理
  6. URAL 1136 Parliament 二叉树水题 BST后序遍历建树
  7. Linux网络管理——网关作用
  8. UVA 10382 - Watering Grass【贪心+区间覆盖问题+高精度】
  9. linux抓包命令之tcpdump
  10. c# 递归函数使用案例
  11. Spring AOP源码分析(三)创建AOP代理
  12. USACO 4.3 Letter Game (字典树)
  13. Effective C++ —— 模板与泛型编程(七)
  14. ubuntu解压命令
  15. 玩转JavaScript module pattern精髓
  16. mysql 数据操作 单表查询 使用正则表达式查询
  17. Java回顾之序列化
  18. 周总结&lt;4&gt;
  19. thinkphp5.0 配置格式
  20. GPIO—位带操作

热门文章

  1. JS的for循环包裹异步函数的问题
  2. 基于FPGA的以太网开发
  3. ARM Cortex-M底层技术(1)—程序在Flash和SRAM的空间分配
  4. 你真的懂git rebase吗?
  5. zookeeper之一 安装和配置(单机+集群)
  6. java术语(PO/POJO/VO/BO/QO/DAO/DTO)
  7. 网络编程基础-socket的简单实用
  8. hihocoder 1582 : Territorial Dispute (计算几何)(2017 北京网络赛E)
  9. 0-4评价一个语言模型Evaluating Language Models:Perplexity
  10. 链表中倒数第k个节点(python)