设计模式之观察者模式

简介: 我们在电视上都看过这样一个场景,一个小孩拿着报纸在街上吆喝着,“卖报了,卖报了,xx鬼子侵占了中国东三省,张学良拱手让人”。然后想细看内容的人就会买一份报纸。又或者我们肯定都存在着这样一个群,这个微信群专门用于通知消息的,只要群里一有消息,我们就会知道。不管是我们订阅报纸的过程,还是接受群通知的过程,这其实就是观察者模式的灵活体现。这篇文章一起来分析了解一下观察者模式。

一、认识观察者模式


首先我们给出观察者模式的定义:

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。


概念很清晰,我们举个例子来理解一下观察者模式的含义,我们都在新浪微博中关注过某一位明星(假设,当然很多人已经不玩微博了),每当这位明星发布一条动态时候,他的粉丝就都会知道。我们使用一张图来表示一下他们的关系。

v2-1be971edc42c5f244ec39e84f6b31d63_1440w.jpg上面这位明星在新浪微博上发了一条动态,说他会唱、跳rap等等。然后他的粉丝就都知道了。从这个例子中我们可以看到,这里包含了两种人,第一种是明星,第二个是粉丝。转化为设计模式中的语言就是主题和观察者。


我们的明星的微博就相当于与一个主题,粉丝就是观察者,随时观察明星的动态。不过明星有权利让你关注,也有权利把你拉黑。现在我们从类图的角度来看一下:

v2-ed9a689d47ce0b18fda0b205f9a6003f_1440w.jpg

从上面我们可以看到,这里面包含了两大类(主题和观察者)一共四个角色:


(1)Subject:抽象主题,他把所有观察者对象保存在一个集合里,可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。意思就是明星把所有的粉丝都保存在一个账号里面,粉丝数量不限,可以新增粉丝也可以拉黑粉丝。


(2)ConcreteSubject:具体主题,该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。意思是我们的明星一有动态,就会把消息给粉丝。


(3)Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。这就是我们所有粉丝的抽象。


(4)ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。具体每一个粉丝。


观察者模式还是比较简单的,就是一个粉丝关注明星的实例。现在代码来实现一下。


二、代码实现观察者模式


这个例子我们还是那上面的例子来解释说明。


第一步:定义抽象观察者(Observer):抽象的粉丝

public interface Fan {
    public void update(String message) ;
}

第二步:具体的观察者(concreteObserver):具体的粉丝

public class ConcreteFan implements Fan {
    private String fanName;
    public ConcreteFan(String fanName) {
        this.fanName=fanName;
    }
    @Override
    public void update(String message) {
        System.out.println(fanName + "知道了:" + message+"  这条消息");
    }
}

第三步:定义抽象主题(Subject):抽象明星

//明星接口:所有的明星都有这样的功能
public interface Idol {
    //增加粉丝
    public void addFan(Fan fan);
    //拉黑粉丝
    public void deFan(Fan fan);
    //告诉粉丝我的动态
    public void notify(String message);
}

第四步:具体主题(ConcreteSubject):具体的明星

public class ConcreteIdol implements Idol{
     //保存所有的粉丝
    private List<Fan> fanList = new ArrayList<Fan>();
    @Override
    public void addFan(Fan fan) {
        fanList.add(fan);//增加粉丝
    }
    @Override
    public void deFan(Fan fan) {
        fanList.remove(fan);//拉黑粉丝
    }
    @Override
    public void notify(String message) {
        for (Fan fan : fanList) {
            fan.update(message);//通知每一个粉丝消息
        }
    }
}

第五步:测试

public class Test {
    public static void main(String[] args) {
        //第一步:有一个明星
        ConcreteIdol idol=new ConcreteIdol();
        //第二步:有很多粉丝,这里给出来三个吧
        ConcreteFan fanA=new ConcreteFan("张三");
        ConcreteFan fanB=new ConcreteFan("李四");
        ConcreteFan fanC=new ConcreteFan("王五");
        //第三步:让粉丝去关注明星(反过来,明星把他们拉进来)
        idol.addFan(fanA);
        idol.addFan(fanB);
        idol.addFan(fanC);
        //第四步:明星发动态,粉丝获取动态
        idol.notify("我会唱、跳、rap、篮球,music");
    }
}
//张三知道了:我会唱、跳、rap、篮球,music  这条消息
//李四知道了:我会唱、跳、rap、篮球,music  这条消息
//王五知道了:我会唱、跳、rap、篮球,music  这条消息

代码就这么多,说起来这个观察者模式还是很简单的。下面我们就来分析一下这个观察者模式


三、分析观察者模式


观察者模式的主要优点在于可以实现表示层和数据逻辑层的分离,并在观察目标和观察者之间建立一个抽象的耦合,支持广播通信;其主要缺点在于如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间,而且如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。


其实还有一点需要我们去了解,在上面的例子当中我们的会发现,其实粉丝的消息是明星推过来的,还有一种观察者模式,也就是我们的粉丝主动去获取消息。


(1)推模型: 主题对象向观察者推送主题的详细信息,不管是否需要。

(2)拉模型:主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取。


OK。观察者模式就先到这,如有问题还请批评指正

相关文章
|
2月前
|
设计模式 PHP
php设计模式--观察者模式(4.1)面向过程完成页面内容切换
php设计模式--观察者模式(4.1)面向过程完成页面内容切换
19 0
|
2月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
2月前
|
设计模式 监控 Java
设计模式 - 观察者模式(Observer):Java中的战术与策略
【4月更文挑战第7天】观察者模式是构建可维护、可扩展系统的关键,它在Java中通过`Observable`和`Observer`实现对象间一对多的依赖关系,常用于事件处理、数据绑定和同步。该模式支持事件驱动架构、数据同步和实时系统,但需注意避免循环依赖、控制通知粒度,并关注性能和内存泄漏问题。通过明确角色、使用抽象和管理观察者注册,可最大化其效果。
|
2月前
|
设计模式 存储 Java
【设计模式】观察者模式
【设计模式】观察者模式
|
24天前
|
设计模式 消息中间件 存储
跟着GPT学设计模式之观察者模式
观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,其依赖对象都能够收到通知并自动更新。一般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者(Observer)。
16 1
|
4天前
|
设计模式 存储 Java
Java设计模式之观察者模式详解
Java设计模式之观察者模式详解
|
5天前
|
设计模式
观察者模式-大话设计模式
观察者模式-大话设计模式
6 0
|
10天前
|
设计模式 存储
行为型设计模式之观察者模式
行为型设计模式之观察者模式
|
2月前
|
设计模式 Java
Java一分钟之-设计模式:观察者模式与事件驱动
【5月更文挑战第17天】本文探讨了Java中实现组件间通信的观察者模式和事件驱动编程。观察者模式提供订阅机制,当对象状态改变时通知所有依赖对象。然而,它可能引发性能问题、循环依赖和内存泄漏。代码示例展示了如何实现和避免这些问题。事件驱动编程则响应用户输入和系统事件,但回调地狱和同步/异步混淆可能造成困扰。JavaFX事件驱动示例解释了如何处理事件。理解这两种模式有助于编写健壮的程序。
30 1
|
23天前
|
设计模式 前端开发 NoSQL
设计模式第八讲:观察者模式和中介者模式详解
 定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
177 0