观察者模式
2019-03-06 10:16 剑动情缥缈 阅读(169) 评论(0) 编辑 收藏 举报1.概念
- 定义了一种一对多的依赖关系,让多个观察者可以监控一个主题对象,当主题对象发生改变,会通知所有的观察者,让他们能够自动更新自己
- UML
- 角色
1)抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。
2)具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
3)抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
4)具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
- 推模型与拉模型
1)推模型:主题将信息推送给观察者,如下代码所示
2)拉模型:主题通知观察者,让观察者自己从主题获取信息
2.代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.chengjie; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 //主题 7 abstract class Subject { 8 private List<Observer> list = new ArrayList<Observer>(); 9 10 public void attach(Observer o) { 11 list.add(o); 12 } 13 14 public void detach(Observer o) { 15 list.remove(o); 16 } 17 18 public void notifyAllObservers(String state) { 19 for (Observer o : list) { 20 o.update(state); 21 } 22 } 23 } 24 25 class RealSubject extends Subject { 26 public String getState() { 27 return state; 28 } 29 30 private String state; 31 32 public void change(String newState) { 33 state = newState; 34 notifyAllObservers(newState); 35 } 36 } 37 38 interface Observer { 39 void update(String state); 40 } 41 42 class RealObserver implements Observer { 43 private String observerState; 44 45 @Override 46 public void update(String state) { 47 observerState = state; 48 System.out.println("RealObserver state:" + observerState); 49 } 50 } 51 52 public class TestObserver { 53 public static void main(String[] args) { 54 //新建主题 55 RealSubject subject = new RealSubject(); 56 57 //新建观察者 58 Observer observer = new RealObserver(); 59 60 //将观察者注册进主题 61 subject.attach(observer); 62 63 //改变主题状态 64 subject.change("a new state"); 65 } 66 }
3.优点
- 观察者与主题是解耦的,可以动态添加观察者与删除观察者
4.缺点
- 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃
5.使用场景
- 一个对象改变需要通知其他对象,而不知道具体对象是谁
- 一个抽象模型改变依赖于另一个模型,将这些方面封装在独立的对象使他们能够独立改变和复用
- 需要在系统中创建一个触发链,A触发B,B触发C
在JAVA语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成JAVA语言对观察者模式的支持。
6.参考
https://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html
http://www.runoob.com/design-pattern/observer-pattern.html