欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java設(shè)計(jì)模式之觀察者模式原理與用法詳解

 更新時(shí)間:2020年06月02日 12:12:54   作者:wit_stan  
這篇文章主要介紹了Java設(shè)計(jì)模式之觀察者模式,結(jié)合實(shí)例形式詳細(xì)分析了Java設(shè)計(jì)模式之觀察者模式基本概念、原理、用法及操作注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了Java設(shè)計(jì)模式之觀察者模式原理與用法。分享給大家供大家參考,具體如下:

什么是觀察者模式


      可以這么理解:

                  觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。

                  這個(gè)主題對(duì)象在狀態(tài)上發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,讓它們能夠自動(dòng)更新自己。

    也可以這樣理解:

                觀察者模式是關(guān)于多個(gè)對(duì)象想知道一個(gè)對(duì)象中數(shù)據(jù)變化情況的一種成熟模式。觀察者模式中有一個(gè)稱作“主題”的對(duì)象和若干個(gè)稱作“觀察者”的對(duì)象,“主題”和“觀察者”之間是一種一對(duì)多的依賴關(guān)系。

                當(dāng)“主題”的狀態(tài)發(fā)生變化時(shí),所有“觀察者”都得到通知。


       日常生活中,最容易理解的例子就是微信公眾號(hào)。我們用微信訂閱的微信公共號(hào)就是這里所說(shuō)的主題,而我們 每一個(gè)關(guān)注這個(gè)微信號(hào)的人就是這里的觀察者。公眾號(hào)每天有更新,所有訂閱者都會(huì)收到。

觀察者模式類圖:

應(yīng)用場(chǎng)景 

         一般被用來(lái)實(shí)現(xiàn)事件處理系統(tǒng)。

觀察者模式組成


        從定義看,可以分成兩個(gè)角色, 觀察者和被觀察對(duì)象(即主題)

        從類圖看,代碼實(shí)現(xiàn)有四個(gè)角色:

  • 抽象主題角色: 把所有對(duì)觀察者對(duì)象的引用保存在一個(gè)集合中,每個(gè)抽象主題角色都可以有任意數(shù)量的觀察者。抽象主題提供一個(gè)接口,可以增加和刪除觀察者角色。一般用一個(gè)抽象類和接口來(lái)實(shí)現(xiàn)。

  • 抽象觀察者角色:為所有具體的觀察者定義一個(gè)接口,在得到主題的通知時(shí)更新自己。

  • 具體主題角色:在具體主題內(nèi)部狀態(tài)改變時(shí),給所有登記過(guò)的觀察者發(fā)出通知。具體主題角色通常用一個(gè)子類實(shí)現(xiàn)。

  • 具體觀察者角色:該角色實(shí)現(xiàn)抽象觀察者角色所要求的更新接口,以便使本身的狀態(tài)與主題的狀態(tài)相協(xié)調(diào)。通常用一個(gè)子類實(shí)現(xiàn)。如果需要,具體觀察者角色可以保存一個(gè)指向具體主題角色的引用。


代碼實(shí)現(xiàn)觀察者模式

  • 抽象主題角色

     主題接口規(guī)定了具體主題需要實(shí)現(xiàn)的添加,刪除及通知觀察者更新數(shù)據(jù)的方法

/**
 * 抽象主題,被觀察者
 *
 */
public interface Subject {
 /**
  * 添加觀察者
  * 
  * @param observer
  */
 void addObserver(Observer observer);
 
 /**
  * 移除指定的觀察者
  * 
  * @param observer
  */
 void removeObserver(Observer observer);
 
 /**
  * 移除所有的觀察者
  */
 void removeAll();
 
 /**
  * data 是要通知給觀察者的數(shù)據(jù) 因?yàn)镺bject是所有類的父類,可以使用多態(tài),當(dāng)然 你也可以使用 泛型
  * 
  * @param data
  */
 void notifyAllObserver(Object data);
 
 /**
  * 單獨(dú) 通知某一個(gè)觀察者
  * 
  * @param observer
  * @param data
  *   data 是要通知給觀察者的數(shù)據(jù) 因?yàn)镺bject是所有類的父類,可以使用多態(tài),當(dāng)然 你也可以使用 泛型
  */
 void notify(Observer observer, Object data);
 
}
  • 抽象觀察者角色

        觀察者接口規(guī)定了具體觀察者用來(lái)更新數(shù)據(jù)的方法

/**
 * 抽象觀察者接口
 */
public interface Observer {
 /**
  * 
  * @param subject 被觀察者
  * @param data 被觀察者傳遞給觀察者的 數(shù)據(jù)
  */
 void update(Subject subject,Object data);
}
  • 具體主題角色
public class ConcreteSubject implements Subject {
 
 //觀察者集合,用于管理所有的觀察者
 List<Observer> mList = new ArrayList<>();
 
 @Override
 public void addObserver(Observer observer) {
  // TODO Auto-generated method stub
  // 確保相同的觀察者只含有一個(gè)
  if (observer == null) {
   throw new NullPointerException("observer == null");
  }
 
  if (!mList.contains(observer)) {
   mList.add(observer);
  }
 }
 
 @Override
 public void removeObserver(Observer observer) {
  // TODO Auto-generated method stub
  mList.remove(observer);
 }
 
 @Override
 public void removeAll() {
  // TODO Auto-generated method stub
  mList.clear();
 }
 
 @Override
 public void notifyAllObserver(Object data) {
  // TODO Auto-generated method stub
  for (Observer observer : mList) {
   observer.update(this, data);
  }
 }
 
 @Override
 public void notify(Observer observer, Object data) {
  // TODO Auto-generated method stub
  if (observer != null) {
   observer.update(this, data);
  }
 }
 
}
  • 具體的觀察者角色

       這里我們可以定義多個(gè)具體的觀察者角色

觀察者One

public class ObserverOne implements Observer {
 
 @Override
 public void update(Subject subject, Object data) {
  // TODO Auto-generated method stub
  System.err
    .println("the messge from subject to-->" + this.getClass().getName() + "<---is " + data.toString());
 }
 
}

觀察者Two

public class ObserverTwo implements Observer {
 
 @Override
 public void update(Subject subject, Object data) {
  // TODO Auto-generated method stub
  System.err
  .println("the messge from subject to-->" + this.getClass().getName() + "<---is " + data.toString());
 }
 
}

觀察者Three

public class ObserverThree implements Observer {
 
 @Override
 public void update(Subject subject, Object data) {
  // TODO Auto-generated method stub
  System.err
  .println("the messge from subject to-->" + this.getClass().getName() + "<---is " + data.toString());
 }
 
}
  • 測(cè)試類
public class TestObservePattern {
 
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  ConcreteSubject concreteSubject = new ConcreteSubject();
  ObserverOne observerOne=new ObserverOne();
  ObserverTwo observerTwo=new ObserverTwo();
  ObserverThree observerThree=new ObserverThree();
  
  concreteSubject.addObserver(observerOne);
  concreteSubject.addObserver(observerTwo);
  concreteSubject.addObserver(observerThree);
  
  
  //通知所有的觀察者
  concreteSubject.notifyAllObserver("wake up,wake up");
  //通知某個(gè)特定的觀察者OberverTwo
  concreteSubject.notify(observerTwo, "Specila msg for you");
  //觀察者ObserveThree 決定不再訂閱主題
  concreteSubject.removeObserver(observerThree);
  //通知所有的觀察者
  concreteSubject.notifyAllObserver("new Message come ");
 }
 
}

更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計(jì)入門與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Java并發(fā)編程:CountDownLatch與CyclicBarrier和Semaphore的實(shí)例詳解

    Java并發(fā)編程:CountDownLatch與CyclicBarrier和Semaphore的實(shí)例詳解

    這篇文章主要介紹了Java并發(fā)編程:CountDownLatch與CyclicBarrier和Semaphore的實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-09-09
  • Java二分查找算法與數(shù)組處理的應(yīng)用實(shí)例

    Java二分查找算法與數(shù)組處理的應(yīng)用實(shí)例

    二分查找法,又叫做折半查找法,它是一種效率較高的查找方法。數(shù)組對(duì)于每一門編程語(yǔ)言來(lái)說(shuō)都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語(yǔ)言對(duì)數(shù)組的實(shí)現(xiàn)及處理也不盡相同。Java 語(yǔ)言中提供的數(shù)組是用來(lái)存儲(chǔ)固定大小的同類型元素
    2022-07-07
  • Java經(jīng)典排序算法之歸并排序?qū)崿F(xiàn)代碼

    Java經(jīng)典排序算法之歸并排序?qū)崿F(xiàn)代碼

    這篇文章主要介紹了Java經(jīng)典排序算法之歸并排序?qū)崿F(xiàn)代碼,歸并排序是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法的一個(gè)非常典型的應(yīng)用,將已有序的子序列合并,得到完全有序的序列,需要的朋友可以參考下
    2023-10-10
  • Java中float類型的范圍及其與十六進(jìn)制的轉(zhuǎn)換例子

    Java中float類型的范圍及其與十六進(jìn)制的轉(zhuǎn)換例子

    這篇文章主要介紹了Java中float類型的范圍及其與十六進(jìn)制的轉(zhuǎn)換例子,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-10-10
  • Kotlin 基礎(chǔ)教程之反射

    Kotlin 基礎(chǔ)教程之反射

    這篇文章主要介紹了Kotlin 基礎(chǔ)教程之反射的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java中I/O流讀取數(shù)據(jù)不完整的問題解決

    Java中I/O流讀取數(shù)據(jù)不完整的問題解決

    本文主要介紹了ava中I/O流讀取數(shù)據(jù)不完整的問題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • spring啟動(dòng)錯(cuò)誤Singleton bean creation not allowed while the singletons of this factory are indestruction

    spring啟動(dòng)錯(cuò)誤Singleton bean creation not al

    本文主要介紹了spring啟動(dòng)錯(cuò)誤Singleton bean creation not allowed while the singletons of this factory are indestruction,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • springboot中RabbitMQ死信隊(duì)列的實(shí)現(xiàn)示例

    springboot中RabbitMQ死信隊(duì)列的實(shí)現(xiàn)示例

    死信隊(duì)列是一種特殊的消息隊(duì)列,用來(lái)存儲(chǔ)無(wú)法被正常消費(fèi)的消息,常被用來(lái)實(shí)現(xiàn)延遲處理,異常消息處理等,本文主要介紹了springboot中RabbitMQ死信隊(duì)列的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2024-01-01
  • 舉例詳解用Java實(shí)現(xiàn)web分頁(yè)功能的方法

    舉例詳解用Java實(shí)現(xiàn)web分頁(yè)功能的方法

    這篇文章主要介紹了舉例詳解用Java實(shí)現(xiàn)web分頁(yè)功能的方法,這種基本功能現(xiàn)一般通過(guò)Hibernate框架來(lái)完成,需要的朋友可以參考下
    2015-10-10
  • Java工廠模式優(yōu)雅地創(chuàng)建對(duì)象以及提高代碼復(fù)用率和靈活性

    Java工廠模式優(yōu)雅地創(chuàng)建對(duì)象以及提高代碼復(fù)用率和靈活性

    Java工廠模式是一種創(chuàng)建型設(shè)計(jì)模式,通過(guò)定義一個(gè)工廠類來(lái)封裝對(duì)象的創(chuàng)建過(guò)程,將對(duì)象的創(chuàng)建和使用分離,提高代碼的可維護(hù)性和可擴(kuò)展性,同時(shí)可以實(shí)現(xiàn)更好的代碼復(fù)用和靈活性
    2023-05-05

最新評(píng)論