设计模式之-观察者模式(Observer Design Pattern)

本文详细介绍了观察者模式的实现方式,包括主题接口、观察者规则、主题内容实现和观察者订阅主题变化的过程。通过一个简单的示例,展示了如何在Java中使用Observer模式,确保当主题内容发生变化时,所有观察者都能接收到通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当你订阅一个感兴趣主题消息,内容发生任何变化时都能够得到通知,观察者模式对你是非常有帮助的。在观察者模式中,一个对象监控另一个对象的状态,那这个对象被称为观察者,被监视的对象被称为主题。

一个主题对象会有很多观察者,当其内容发生改变时会通知所有观察者。主题需提供是观察者自身可以注册(订阅)和注销(取消订阅)方法,主题还包含一个方法来通知任何改变到所有的观察者,使它可以发送更新通知,而观察者也可以提供另一种方法来获取更新。

Java提供了Observer模式的实现,通过java.util.Observable类和java.util.Observer接口实现Observer模式。但是它没有被广泛使用,因为实现是非常简单的,大部分的时候,我们不会为了只是实现观察者模式而轻易的去继承一个类,因为Java不提供多重继承。


Observer模式实现:

在这个例子中,我们只实现了一个简单的主题以及观察者可以进行订阅功能。每当有新的消息发布到这个主题所有的观察者都会被通知到并及时使用它们。

基本主题接口定义了基本方法,具体的主题子类去实现


Subject.java

package com.journaldev.design.observer;
 
public interface Subject {
 
    //methods to register and unregister observers
    publicvoidregister(Observer obj);
    publicvoidunregister(Observer obj);
     
    //method to notify observers of change
    publicvoidnotifyObservers();
     
    //method to get updates from subject
    publicObject getUpdate(Observer obj);
     
}

下一步,我们将建立Observer规则,将有一个方法用来设置符合观察者感兴趣内容和获取主题更新内容方法

Observer.java

package com.journaldev.design.observer;
 
public interface Observer {
     
    //method to update the observer, used by subject
    public void update();
     
    //attach with subject to observe
    public void setSubject(Subject sub);
}

现在Observer规则已制定好,让我们实现和处理我们的主题内容


package com.journaldev.design.observer;
 
import java.util.ArrayList;
import java.util.List;
 
public class MyTopic implements Subject {
 
    private List<Observer> observers;
    private String message;
    private boolean changed;
    private final Object MUTEX= new Object();
     
    public MyTopic(){
        this.observers=new ArrayList<>();
    }
    @Override
    public void register(Observer obj) {
        if(obj == null) throw new NullPointerException("Null Observer");
        synchronized (MUTEX) {
        if(!observers.contains(obj)) observers.add(obj);
        }
    }
 
    @Override
    public void unregister(Observer obj) {
        synchronized (MUTEX) {
        observers.remove(obj);
        }
    }
 
    @Override
    public void notifyObservers() {
        List<Observer> observersLocal = null;
        //synchronization is used to make sure any observer registered after message is received is not notified
        synchronized (MUTEX) {
            if (!changed)
                return;
            observersLocal = new ArrayList<>(this.observers);
            this.changed=false;
        }
        for (Observer obj : observersLocal) {
            obj.update();
        }
 
    }
 
    @Override
    public Object getUpdate(Observer obj) {
        return this.message;
    }
     
    //method to post message to the topic
    public void postMessage(String msg){
        System.out.println("Message Posted to Topic:"+msg);
        this.message=msg;
        this.changed=true;
        notifyObservers();
    }
 
}

这里简单实现了Obsever注册与注销,postMessage()方法用于更新主题消息,请注意,布尔变量作用,为保持在题目的状态的变化的轨迹和在通知观察者使用。这个变量是必需的,因此,如果没有及时更新,有人呼吁notifyObservers()方法时,它不发送虚假通知给观察者。

同时注意在notifyObservers()方法中使用了同步,用于确保该通知只发布给通知发布前注册的observer


Observer实现观察订阅主题变化:

MyTopicSubscriber.java

package com.journaldev.design.observer;
 
public class MyTopicSubscriber implements Observer {
     
    private String name;
    private Subject topic;
     
    public MyTopicSubscriber(String nm){
        this.name=nm;
    }
    @Override
    public void update() {
        String msg = (String) topic.getUpdate(this);
        if(msg == null){
            System.out.println(name+":: No new message");
        }else
        System.out.println(name+":: Consuming message::"+msg);
    }
 
    @Override
    public void setSubject(Subject sub) {
        this.topic=sub;
    }
 
}

注意的update()方法它调用TopicgetUpdate()方法来获取信息来实现。我们本来可以避免通过传递具体的消息作为参数传递给update()方法。

测试类

package com.journaldev.design.observer;
 
public class ObserverPatternTest {
 
    public static void main(String[] args) {
        //create subject
        MyTopic topic = new MyTopic();
         
        //create observers
        Observer obj1 = new MyTopicSubscriber("Obj1");
        Observer obj2 = new MyTopicSubscriber("Obj2");
        Observer obj3 = new MyTopicSubscriber("Obj3");
         
        //register observers to the subject
        topic.register(obj1);
        topic.register(obj2);
        topic.register(obj3);
         
        //attach observer to subject
        obj1.setSubject(topic);
        obj2.setSubject(topic);
        obj3.setSubject(topic);
         
        //check if any update is available
        obj1.update();
         
        //now send message to subject
        topic.postMessage("New Message");
    }
 
}

输出结果:

Obj1:: No new message
Message Posted to Topic:New Message
Obj1:: Consuming message::New Message
Obj2:: Consuming message::New Message
Obj3:: Consuming message::New Message


Observer Pattern Class Diagram



原文链接:http://www.journaldev.com/1739/observer-design-pattern-in-java


转载于:https://www.cnblogs.com/happyxiaoyu02/p/6818943.html

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在 IT 领域,文档格式转换是常见需求,尤其在处理多种文件类型时。本文将聚焦于利用 Java 技术栈,尤其是 Apache POI 和 iTextPDF 库,实现 doc、xls(涵盖 Excel 2003 及 Excel 2007+)以及 txt、图片等格式文件向 PDF 的转换,并实现在线浏览功能。 先从 Apache POI 说起,它是一个强大的 Java 库,专注于处理 Microsoft Office 格式文件,比如 doc 和 xls。Apache POI 提供了 HSSF 和 XSSF 两个 API,其中 HSSF 用于读写老版本的 BIFF8 格式(Excel 97-2003),XSSF 则针对新的 XML 格式(Excel 2007+)。这两个 API 均具备读取和写入工作表、单元格、公式、样式等功能。读取 Excel 文件时,可通过创建 HSSFWorkbook 或 XSSFWorkbook 对象来打开相应格式的文件,进而遍历工作簿中的每个 Sheet,获取行和列数据。写入 Excel 文件时,创建新的 Workbook 对象,添加 Sheet、Row 和 Cell,即可构建新 Excel 文件。 再看 iTextPDF,它是一个用于生成和修改 PDF 文档的 Java 库,拥有丰富的 API。创建 PDF 文档时,借助 Document 对象,可定义页面尺寸、边距等属性来定制 PDF 外观。添加内容方面,可使用 Paragraph、List、Table 等元素将文本、列表和表格加入 PDF,图片可通过 Image 类加载插入。iTextPDF 支持多种字体和样式,可设置文本颜色、大小、样式等。此外,iTextPDF 的 TextRenderer 类能将 HTML、
资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 VESA DSC(Display Stream Compression)是由视频电子标准协会(Video Electronics Standards Association)推出的一种高效低延迟的图像数据压缩技术,主要用于缓解高分辨率、高刷新率显示系统中显示接口的数据传输压力。它在不降低画质的前提下,可显著降低带宽需求,从而提升显示系统性能。VESA DSC有多个版本,从 v1.1 到 v1.2b,每个版本都对前一版本进行了改进和优化,比如修复错误、提升性能或增强兼容性。其中,v1.1 是基础版本,v1.2 系列则是对原始规范的逐步完善,v1.2a 和 v1.2b 通常是针对特定问题或新需求的微调版本。 DSC 压缩规格说明书详细介绍了 DSC 的工作原理、编码流程、解码算法以及与显示系统的接口规范,涵盖以下关键点:1. 压缩算法:DSC 结合了熵编码和预测编码,通过预测连续像素间的差异来减少传输信息量,其中熵编码单元(EEU)和熵解码单元(EDU)负责数据的编码和解码。2. 帧内和帧间预测:DSC 支持基于同一帧内像素信息的帧内预测,以及利用前后帧像素关系的帧间预测,从而在保持画质的同时提高压缩效率。3. 带宽管理:DSC 标准可动态调整压缩比率,以适配显示设备的实际带宽需求,确保流畅显示。4. 实时性和低延迟:DSC 设计时注重实时应用,尽可能减少压缩和解压缩过程中的延迟,这对于游戏和专业图形应用至关重要。5. 兼容性和互操作性:作为 VESA 的标准,DSC 与其他显示接口标准(如 HDMI、DP 等)兼容,保证不同设备间的互操作性。6. C Model 源码:提供的 C 模型源码是 DSC 算法的参考实现,有助于开发者理解 DSC 工作机制,用于开发 DSC 兼容的硬件或软件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值