设计模式-观察者模式


定义

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,所有依赖与他的状态都会被通知到。

使用场景

Subject 抽象的主题,也就是被观察者的角色,抽象主题角色把所有观察者对象的引用存在一个集合中,每个主题都可以有任意数量的观察者,抽象主题提供接口,可以增加删除观察者对象。

ConcreteSubject 具体,该角色将有关状态存在具体观察者对象,具体内部发生变化的时候,给所有注册过的通知者发出通知,具体主题角色又叫做具体被观察者

Observer 抽象观察者,该角色是观察者的抽象类,它定义了一个更新接口,使得在得到主题的更改通知的时候更新自己

ConCreteObserver 具体的观察者,该角色实现抽象观察者实现的接口,以便在主题变化的时候更新自身状态

UML图

观察者模式类图

代码案例

最简单的例子


public class Coder implements Observer {
    private String name;

    public  Coder(String name){
        this.name=name;
    }
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("收到通知");
    }
}
public class DevTechFrontier extends Observable {
    public void postNewTouchPublication(String content) {
        setChanged();
        notifyObservers();
    }
}

class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
        val devTechFrontier = DevTechFrontier()

        val coder = Coder("coder1")

        devTechFrontier.addObserver(coder)

        devTechFrontier.postNewTouchPublication("新的技术周刊发布")
    }
}

常用的例子
因为Observable和Observer 是内嵌入JDK中的所以可以直接可以用到,后续一般情况下可以比如Observer 这个接口放在 Observable的一个map或者list之中,在需要通知的时候遍历这个集合回调即可,当然 需要给出的是一个注册和取消注册的方法。


interface WeatherObserver {
    void notifyWeather();
}
public class BeiJingWeather implements WeatherObserver {
    @Override
    public void notifyWeather() {
        System.out.println("notifyWeather:这里是北京,收到通知 ");
    }
}

public class GuangDongWeather implements WeatherObserver {
    @Override
    public void notifyWeather() {
        System.out.println("notifyWeather:这里是广东,收到通知 ");

    }
}

package com.example.leak.observer;

import java.util.List;

public class WeatherObservable {
    private List<WeatherObserver> list;
    public void resiter(WeatherObserver observer) {
        list.add(observer);
    }
    public void unresiter(WeatherObserver observer) {
        list.remove(observer);
    }
    public void notifyAllWeather() {
        for (int i = 0; i <list.size() ; i++) {
            list.get(i).notifyWeather();
        }
    }
}

这种自己实现的观察者模式才是比较常见能解耦两个模块

优缺点
1.观察者模式和被观察者之间是抽象耦合,应对业务变化
2.增强系统灵活性,可扩展性

缺点
在应用观察者模式时,需要考虑一下开发效率和运行效率问题


  TOC