观察者模式

  1. Observer
    1. 观察者模式: 警察与罪犯
    2. Java源码中的观察者模式

Observer

观察者模式: 警察与罪犯

处理一对多的依赖关系,被观察的对象改变时,多个观察者都能收到通知

DesignPatternofObserver

众所周知,张三坏事做尽,是一个老法外狂徒了,所以不止一个警察会盯着张三,也就是说一个被观察者可以有多个观察者。当被观察者有事件发生时,所有观察者都能收到通知并响应。观察者模式主要处理的是一种一对多的依赖关系。它的定义如下:

观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

观察者的接口:

package com.DesignPattern.Observer;

// 观察者接口 --- 基类1
public interface Observer {
    // 接口中只有一个 update 方法,用于对被观察者发出的事件做出响应。
    void update(String event);
}

被观察者中维护了一个观察者列表,提供了三个方法:

  • addObserver:将 observer 对象添加到观察者列表中
  • removeObserver:将 observer 对象从观察者列表中移除
  • notifyObservers:通知所有观察者有事件发生,具体实现是调用所有观察者的 update 方法
package com.DesignPattern.Observer;

import java.util.ArrayList;
import java.util.List;

// 被观察者的父类:--- 基类2
public class Observable {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers(String event) {
        for (Observer observer : observers) {
            observer.update(event);
        }
    }
}

警察属于观察者:

package com.DesignPattern.Observer;

// 警察属于观察者:
public class PoliceObserver  implements Observer{

    // 响应
    @Override
    public void update(String event) {
        // 警察实现了观察者接口,当警察收到事件后,做出响应,这里的响应就是简单的打印了一条日志。
        System.out.println("警察收到消息,罪犯在" + event);
    }
}

罪犯继承自被观察者类,当罪犯有犯罪行为时,所有的观察者都会收到通知。

package com.DesignPattern.Observer;

// 罪犯属于被观察者:
public class CriminalObservable extends Observable{
    // 罪犯继承自被观察者类,当罪犯有犯罪行为时,所有的观察者都会收到通知。
    public void crime(String event) {
        System.out.println("罪犯正在" + event);
        notifyObservers(event);
    }
}

在客户端中,我们 new 了一个张三,为其添加了三个观察者:police1,police2,police3。

package com.DesignPattern.Observer;


import org.junit.Test;

public class Client {
    @Test
    public void test(){
        // 被观察者
        CriminalObservable zhangSan = new CriminalObservable();
        // 观察者
        PoliceObserver police1 = new PoliceObserver();
        PoliceObserver police2 = new PoliceObserver();
        PoliceObserver police3 = new PoliceObserver();
        // 订阅 或 注册
        zhangSan.addObserver(police1);
        zhangSan.addObserver(police2);
        zhangSan.addObserver(police3);
        // 张三违法, 警察抓捕
        zhangSan.crime("在嫖娼");
    }
}

输出:

罪犯正在在嫖娼
警察收到消息,罪犯在在嫖娼
警察收到消息,罪犯在在嫖娼
警察收到消息,罪犯在在嫖娼

Java源码中的观察者模式

Java源码中的观察者模式

java.util.Observable 类:

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    public Observable() {
        obs = new Vector<>();
    }

    public synchronized void addObserver(java.util.Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    public synchronized void deleteObserver(java.util.Observer o) {
        obs.removeElement(o);
    }

    public void notifyObservers() {
        notifyObservers(null);
    }

    public void notifyObservers(Object arg) {
        Object[] arrLocal;
        synchronized (this) {
            if (!hasChanged())
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }
        for (int i = arrLocal.length - 1; i >= 0; i--)
            ((Observer) arrLocal[i]).update(this, arg);
    }

    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    protected synchronized void setChanged() {
        changed = true;
    }

    protected synchronized void clearChanged() {
        changed = false;
    }

    public synchronized boolean hasChanged() {
        return changed;
    }

    public synchronized int countObservers() {
        return obs.size();
    }
}

image-20210909151133658


来源: https://leetcode-cn.com/leetbook/read/design-patterns/9emig1/


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jungle8884@163.com

×

喜欢就点赞,疼爱就打赏