目录
当一个对象发生修改时,需要通知多方。
很自然就会想到回调,这个就是观察者模式的核心,观察者模式可以将大量的回调解耦,从而使代码更加优雅。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:使用面向对象技术,可以将这种依赖关系弱化。
关键代码:在抽象类里有一个 ArrayList 存放观察者们。
- import java.util.ArrayList;
- import java.util.List;
-
- public class Subject {
-
- private List
observers - = new ArrayList
(); - private int state;
-
- public int getState() {
- return state;
- }
-
- public void setState(int state) {
- this.state = state;
- notifyAllObservers();
- }
-
- public void attach(Observer observer){
- observers.add(observer);
- }
-
- public void notifyAllObservers(){
- for (Observer observer : observers) {
- observer.update();
- }
- }
- }
接下来定义它的观察者们
- public abstract class Observer {
- protected Subject subject;
- public abstract void update();
- }
编写Observer的实现类
- public class BinaryObserver extends Observer{
-
- public BinaryObserver(Subject subject){
- this.subject = subject;
- this.subject.attach(this);
- }
-
- @Override
- public void update() {
- System.out.println( "Binary String: "
- + Integer.toBinaryString( subject.getState() ) );
- }
- }
- public class OctalObserver extends Observer{
-
- public OctalObserver(Subject subject){
- this.subject = subject;
- this.subject.attach(this);
- }
-
- @Override
- public void update() {
- System.out.println( "Octal String: "
- + Integer.toOctalString( subject.getState() ) );
- }
- }
- public class HexaObserver extends Observer{
-
- public HexaObserver(Subject subject){
- this.subject = subject;
- this.subject.attach(this);
- }
-
- @Override
- public void update() {
- System.out.println( "Hex String: "
- + Integer.toHexString( subject.getState() ).toUpperCase() );
- }
- }
使用
- public class ObserverPatternDemo {
- public static void main(String[] args) {
- Subject subject = new Subject();
-
- new HexaObserver(subject);
- new OctalObserver(subject);
- new BinaryObserver(subject);
-
- System.out.println("First state change: 15");
- subject.setState(15);
- System.out.println("Second state change: 10");
- subject.setState(10);
- }
- }
Java的JDK中,已经实现观察者模式的相关代码
JDK中提供了Observable抽象类、以及Observer接口
Observable:可被观察的
主要包含两个方法:
setChanged()
每次状态发生变更,都需要手动调用setChanged
如果需要通知观察者,则需要调用
notifyObservers()
注意:如果在调用notifyObservers()方法之前没有调用setChanged()方法,就不会有什么动作发生。
notifyObservers()方法中包含clearChanged()方法,将标志变量置回原值。
notifyObservers()方法采用的是从后向前的遍历方式,即最后加入的观察者最先被调用update()方法。
- package com.learnjava.observer;
-
- import java.util.Observable;
- import java.util.Observer;
-
- class WatchedCounter extends Observable
- {
- public void countdown(int number)
- {
- for (; number >= 0; --number)
- {
- // 设置改变变量
- setChanged();
-
- // 通知所有观察者,将number作为参数信息传递给观察者
- notifyObservers(number);
-
- }
-
- }
- }
-
- class Watcher1 implements Observer
- {
- @Override
- public void update(Observable arg0, Object arg1)
- {
- System.out.println("Watcher1's number: " + arg1);
-
- }
- }
-
- class Watcher2 implements Observer
- {
- @Override
- public void update(Observable arg0, Object arg1)
- {
-
- if (((Integer) arg1).intValue() <= 5)
- {
- System.out.println("Watcher2's number: " + arg1);
- }
- }
- }
-
- public class ObserverTest
- {
- public static void main(String[] args)
- {
- WatchedCounter watchedCounter = new WatchedCounter();
- Watcher1 watcher1 = new Watcher1();
- Watcher2 watcher2 = new Watcher2();
-
- //添加观察者
- watchedCounter.addObserver(watcher1);
- watchedCounter.addObserver(watcher2);
-
- //开始倒数计数
- watchedCounter.countdown(10);
- }
-
- }