java觀察者模式

来源:http://www.cnblogs.com/intsmaze/archive/2016/10/31/6017508.html
-Advertisement-
Play Games

像activeMQ等消息隊列中,我們經常會使用發佈訂閱模式,但是你有沒有想過,客戶端時如何及時得到訂閱的主題的信息?其實就裡就用到了觀察者模式。在軟體系統中,當一個對象的行為依賴於另一個對象的狀態時,觀察者模式就相當有用。如果不使用觀察者模式提供的通用結構,而需要我們實現類似的功能,想想我們該如何實 ...


   像activeMQ等消息隊列中,我們經常會使用發佈訂閱模式,但是你有沒有想過,客戶端時如何及時得到訂閱的主題的信息?其實就裡就用到了觀察者模式。在軟體系統中,當一個對象的行為依賴於另一個對象的狀態時,觀察者模式就相當有用。如果不使用觀察者模式提供的通用結構,而需要我們實現類似的功能,想想我們該如何實現,我們只能在另外一個線程不斷監聽對象所依賴的狀態。當然下麵的例子都是基於一個進程內觀察者模式的舉例,你可能會和我當初一樣不解,消息隊列中的消費者是通過socket進行通信得到訂閱的主題的信息。其實還是一回事的,被觀察者(主題)裡面會維護一個與它有訂閱的所有消費者的連接,當被觀察者(主題)裡面添加一個消息時,就會調用自身的方法,把該消息通過維持的socket發送給所有訂閱的消費者。   下次再跳槽,我就不是僅僅調侃我掌握kafka等消息隊列的特性了,我又可以結合設計模式來侃我對消息隊列的理解,這個逼吹的響亮吧。     觀察者模式可以用於事件監聽,通知發佈等場合。可以確保觀察者在不使用輪詢監控的情況下,及時收到相關的消息和事件。

原文和作者一起討論:http://www.cnblogs.com/intsmaze/p/6017508.html

新浪微博:intsmaze劉洋洋哥

模式動機     建立一種對象與對象之間的依賴關係,一個對象發生改變時將自動通知其他對象,其他對象將相應做出反應。在此,發生改變的對象稱為觀察目標,而被通知的對象稱為觀察者,一個觀察目標可以對應多個觀察者,而且這些觀察者之間沒有相互聯繫,可以根據需要增加和刪除觀察者,使得系統更易於擴展,這就是觀察者模式的模式動機。   模式定義     觀察者模式(Observer Pattern):定義對象間的一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象皆得到通知並被自動更新。觀察者模式又叫做發佈-訂閱(Publish/Subscribe)模式。觀察者模式是一種對象行為型模式。 模式分析     觀察者模式描述瞭如何建立對象與對象之間的依賴關係,如何構造滿足這種需求的系統。這一模式中的關鍵對象是觀察目標和觀察者,一個目標可以有任意數目的與之相依賴的觀察者,一旦目標的狀態發生改變,所有的觀察者都將得到通知。作為對這個通知的響應,每個觀察者都將即時更新自己的狀態,以與目標狀態同步,這種交互也稱為發佈-訂閱(publish-subscribe)。目標是通知的發佈者,它發出通知時並不需要知道誰是它的觀察者,可以有任意數目的觀察者訂閱它並接收通知。 觀察者模式順序圖如下所示: 模式應用 (1) JDK1.1版本及以後的各個版本中,事件處理模型採用基於觀察者模式的委派事件模型(Delegation Event Model, DEM)。 在DEM中,事件的發佈者稱為事件源(Event Source),而訂閱者叫做事件監聽器(Event Listener),在這個過程中還可以通過事件對象(Event Object)來傳遞與事件相關的信息,可以在事件監聽者的實現類中實現事件處理,因此事件監聽對象又可以稱為事件處理對象。 事件源對象、事件監聽對象(事件處理對象)和事件對象構成了Java事件處理模型的三要素。 (2) 除了AWT中的事件處理之外,Java語言解析XML的技術SAX2以及Servlet技術的事件處理機制都基於DEM,它們都是觀察者模式的應用。 (3) 觀察者模式在軟體開發中應用非常廣泛,如某電子商務網站可以在執行發送操作後給用戶多個發送商品打折信息,某團隊戰鬥游戲中某隊友犧牲將給所有成員提示等等,凡是涉及到一對一或者一對多的對象交互場景都可以使用觀察者模式。    Java語言提供的對觀察者模式的支持
    在java.util.Observable類中,已經實現了主要的功能,如增加觀察者,刪除觀察者和通知觀察者,我們可以直接通過繼承Observable使用這些功能。     java.util.Observer介面是觀察者介面,它的update方法會在java.util.Observable中的notifyObservers方法中被回調,以獲得最新的狀態變化。通常在觀察者模式中,Observer介面就是我們程式的核型擴展對象,具體業務邏輯會被封裝在update方法中。
public class Observable {      
    private boolean changed = false;      
    private Vector obs;      
         
    //創建被觀察者時就創建一個它持有的觀察者列表,註意,這個列表是需要同步的。      
    public Observable() {      
        obs = new Vector();      
    }      
     
    /**    
     * 添加觀察者到觀察者列表中去    
     */     
    public synchronized void addObserver(Observer o) {      
        if (o == null)      
            throw new NullPointerException();      
    if (!obs.contains(o)) {      
        obs.addElement(o);      
    }      
    }      
     
    /**    
     * 刪除一個觀察者    
     */     
    public synchronized void deleteObserver(Observer o) {      
        obs.removeElement(o);      
    }           
     
    /**    
     * 這個方法接受一個參數,這個參數一直傳到觀察者里,以供觀察者使用    
     */     
    public void notifyObservers(Object arg) {                
       Object[] arrLocal;           
       synchronized (this) {      
        if (!changed)      
                return;      
            arrLocal = obs.toArray();      
            clearChanged();      
        }      
        for (int i = arrLocal.length-1; i>=0; i--)      
            ((Observer)arrLocal[i]).update(this, arg);      
    }      
}     

public interface Observer {      
    void update(Observable o, Object arg);       
}    
     
public class JMSObserver implements Observer{          
    public void update(Observable o, Object arg) {      
        System.out.println("發送消息給jms伺服器的觀察者已經被執行");      
    }      
}     
public class Subject extends Observable{      
          
    /**    
     * 業務方法,一旦執行某個操作,則通知觀察者,在隊列模式中,其實就是當消息被添加到隊列的時候,添加進隊方法裡面調用了通知方法。    
     */     
    public void doBusiness(){      
        if (true) {      
            super.setChanged();      
        }      
        notifyObservers("現在還沒有的參數");      
    }      
     
          
    public static void main(String [] args) {      
        //創建一個被觀察者      
        Subject subject = new Subject();      
              
        //創建觀察者      
        Observer jmsObserver = new JMSObserver();      
              
        //把兩個觀察者加到被觀察者列表中        
        subject.addObserver(jmsObserver);      
              
        //執行業務操作      
        subject.doBusiness();      
    }      
}    
MVC模式(有空,研究代碼好好理解,有時加分調侃項目)     MVC模式是一種架構模式,它包含三個角色:模型(Model),視圖(View)和控制器(Controller)。觀察者模式可以用來實現MVC模式,觀察者模式中的觀察目標就是MVC模式中的模型(Model),而觀察者就是MVC中的視圖(View),控制器(Controller)充當兩者之間的中介者(Mediator)。當模型層的數據發生改變時,視圖層將自動改變其顯示內容。

 

     
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作為老牌的 ORM 框架,Hibernate 在推動資料庫持久化層所做出的貢獻有目共睹。 它所提供的數據查詢方式也越來越豐富,從 SQL 到自創的 HQL,再到面向對象的標準化查詢。 雖然查詢方式有點眼花繚亂,配置使用起來也稍微有點複雜。 但是絲毫掩蓋不了它迷人的地方,本篇博客試著彙總 Hibern ...
  • IDEA14創建Maven管理的SpringMVC+Mybatis,web項目 項目構建步驟 1、File->New->Project 勾選Create from archetype 點擊Next 2、輸入GroupId、ArtifactId 點擊Next 3、繼續點擊Next,輸入Project ...
  • 首先,有一個例子 運行這個小例子,會發現是T1和T2是非同步,T3與其他兩個是同步的,顯然T3有鎖被T1或者T2拿到了。如上圖所示。 首先,T1和T2是非同步的很好理解,一個獲取的鎖是當前對象,一個獲取的是類,不是一樣的當然是非同步。 那麼看T3: 將t1.start()這個代碼註掉,查看結果: 非同步的, ...
  • logging模塊 很多程式都有記錄日誌的需求,並且日誌中包含的信息即有正常的程式訪問日誌,還可能有錯誤、警告等信息輸出,python的logging模塊提供了標準的日誌介面,你可以通過它存儲各種格式的日誌,logging的日誌可以分為 debug、info、warning、error、critic ...
  • mybatis generator 修改xml文件後啟動Tomcat伺服器時出現的Result Maps collection already contains value for BaseResultMap異常, ...
  • 1. java程式 2 編譯 javac TestHello.java 3. 生成c++頭文件 javah TestHello 4. 創建 DLL動態鏈接庫工程 TestHello visual studio 2010: File->new->project->win32 project-> dll ...
  • #!/usr/bin/env python# -*- coding: utf-8 -*-#如下是一個購物程式:#先輸入工資,顯示商品列表,購買,quit退出,最後格式化輸出所買的商品。count = 0while True: #做一個迴圈判斷,如果輸入的不是數字,基於提示,三次後退出 salary ...
  • 1.1概述 定義一個用於創建對象的介面,讓子類決定實例化哪一個類。Factory Method使一個類的實例化延遲到其子類。這就是工廠方法模式的定義。 得到一個類的子類的實例最常用的辦法就是使用new運算符和該子類的構造方法,但是在某些情況下,用戶可能不應該或無法使用這種辦法來得到一個子類的實例,其 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...