观察者模式

什么是观察者模式


    观察者模式又叫发布/订阅模式,属于行为模式的一种,他的作用就是当一个对象的状态发生改变时能够自动通知其它关联对象。Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持同步状态。

观察者模式中的角色
    Subject(被观察者): 维护观察者对象列表,当被观察者对象发生改变时需要通知队列中所有观察者对象。
    被观察者具体实现:包含一些基本的属性状态及其他操作。
    Observer(观察者):接口或者抽象类,当被观察者状态发生变化时,Observer对象将通过一个回调函数得到通知。
    观察者具体实现:得到通知后将完成一些具体的业务逻辑处理。

观察者模式实现
    1:可以使用java内置的Observable,Observer实现观察者模式
      内置的观察者模式已经在jdk9中废除,原因是 子类不能序列化,线程不安全。
    2:可以自定义实现

观察者模式的应用场景
    一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

    侦听/监视某个对象的状态变化。

观察者模式优缺点
    优点:被观察者和观察者是松耦合关系
    缺点:观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
         如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

代码实现:

1、首先定义抽象的观察者(谁订阅了天气预报,龙王还是人):

//抽象观察者角色
interface People {
    void update(String str);
}

2、然后定义抽象的主题角色,即抽象的被观察者,在其中声明方法(添加、移除观察者,通知观察者):

//抽象主题角色,watched:被观察
interface Watched {
    void addPeople(People people);

    void removePeople(People people);

    void notifyPeoples(String str);
}

3、然后定义具体的观察者(那些人订阅了天气预报):

//定义两个人关注了天气预报
class ConcretePeople1 implements People {
    @Override
    public void update(String str) {
        System.out.println("ConcretePeople1接受到被观察者的信息是:" + str);
    }
}
class ConcretePeople2 implements People {
    @Override
    public void update(String str) {
        System.out.println("ConcretePeople2接受到被观察者的信息是:" + str);
    }
}

4、之后是具体的主题角色:

class ConcreteWatched implements Watched {
    //定义一个存放观察者的集合
    private List<People> list = new ArrayList<>();
    @Override
    public void addPeople(People people) {
        list.add(people);
    }
    @Override
    public void removePeople(People people) {
        list.remove(people);
    }
    // 自动调用实际上是主题进行调用的
    @Override
    public void notifyPeoples(String str) {
        for (People people : list) {
            people.update(str);
        }
    }
}

5、编写测试类:

public class Test {
    public static void main(String[] args) {
        Watched watched = new ConcreteWatched();
        watched.addPeople(new ConcretePeople1());
        People people = new ConcretePeople2();
        watched.removePeople(people);
        watched.notifyPeoples("今天阴天");
    }
}

运行结果如下:

 例子参考:

https://www.cnblogs.com/mengdd/archive/2013/02/07/2908929.html

原文地址:https://www.cnblogs.com/lzghyh/p/12587122.html