国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

JDK Observer設(shè)計模式之研究

2019-11-18 16:00:37
字體:
供稿:網(wǎng)友

  目前設(shè)計模式的介紹性文章越來越多,但設(shè)計模式的研究性文章仍然比較欠缺,這著實讓人覺得有點遺憾。本文旨在拋磚引玉,具體分析一下java中jdk自帶的observer設(shè)計模式(下文如沒非凡指出,observer設(shè)計模式就意指java中jdk自帶的observer設(shè)計模式)的實現(xiàn)。

  1.Observer設(shè)計模式概要

   Observer設(shè)計模式在GOF里屬于行為設(shè)計模式。JDK里提供的observer設(shè)計模式的實現(xiàn)由java.util.Observable類和java.util.Observer接口組成。從名字上可以清楚的看出兩者在Observer 設(shè)計模式中分別扮演的角色:Observer是觀察者角色,Observable是被觀察目標(biāo)(subject)角色。

   Observable是一個封裝subject基本功能的類,比如注冊observer(attach功能),注銷observer(detatch功能)等。這些功能是任何一個扮演observerable角色的類都需要實現(xiàn)的,從這一點上來講,JDK里將這些通用功能專門封裝在一個類里,顯得合情合理。通常情況下,我們的類只要從Observerable類派生就可以稱為observerable角色類,使用非常簡單。

  2.使用observer設(shè)計模式存在的困難

  但我們不得不注重到,在項目實際開發(fā)當(dāng)中,情況往往要復(fù)雜得多。java不支持多繼續(xù)特性在很多時候是阻礙我們使用observer設(shè)計模式的絆腳石。比如說,我們設(shè)計的一個類已經(jīng)是某個類的派生類,在這種情況下同時想讓它扮演observerable角色將變得麻煩。如何實現(xiàn)“多繼續(xù)”的效果是擺在我們面前的一大難題。下面我們首先分析一下Observable類。

  3.Observable類“觸發(fā)通知”的原理

  Observable必須“有變化”才能觸發(fā)通知observer這一任務(wù),這是它的本質(zhì)體現(xiàn)。查看源碼便可知一二。Observerable部分源碼如下:

  //……省略……
  PRivate boolean changed = false;
  //……省略……
  public void notifyObservers(Object arg) {
  //……省略……
    Object[] arrLocal;
    synchronized (this) {
     //……省略……
     if (!changed)
      return
;
      arrLocal = obs.toArray();
      clearChanged();
    }

  //……省略……
  protected synchronized void setChanged() {
   changed = true;
  }
 
  protected synchronized void clearChanged() {
   changed = false;
  }

  正如粗的斜體標(biāo)注部分所示,在notifyObservers(Object arg) 方法里if (!changed) return;語句告訴我們,若changed屬性值為false,將直接返回,根本不會觸發(fā)通知操作。并且我們注重到changed 屬性被初始化為false,這將意味著假如我們不主動設(shè)置changed屬性為true,將不會有任何變化,也就是說根本起不到“通知”作用。因此,設(shè)置changed屬性的值是我們應(yīng)用jdk observer 設(shè)計模式的要害所在。那么如何才能設(shè)置changed屬性呢?從源碼可以看出,唯一的入口是通過setChanged()。下面我們分析一下changed屬性及相關(guān)的方法setChanged()和clearChanged()。 QQRead.com 推出數(shù)據(jù)恢復(fù)指南教程 數(shù)據(jù)恢復(fù)指南教程 數(shù)據(jù)恢復(fù)故障解析 常用數(shù)據(jù)恢復(fù)方案 硬盤數(shù)據(jù)恢復(fù)教程 數(shù)據(jù)保護(hù)方法 數(shù)據(jù)恢復(fù)軟件 專業(yè)數(shù)據(jù)恢復(fù)服務(wù)指南
  4.Observable類的分析

  Observable#changed屬性的初始值為false,這很輕易理解,不再具體陳述。細(xì)心的讀者可能會注重到跟changed屬性有關(guān)的兩個方法setChanged()和clearChanged(),它們的修飾符都是protected。想強(qiáng)調(diào)的是,是protected,而不是public。但這樣是否有其必要性和合理性?答案是肯定的。在前面的分析中,我已經(jīng)提到,setChanged()方法是設(shè)置changed的唯一入口,它的修飾符定義為protected,就意味著通過定義Observable的對象,再設(shè)置changed屬性將變得不可能。從這個意義上說,要想應(yīng)用observer設(shè)計模式,必須繼續(xù)Observable類方可。關(guān)于這一點,下文還會提及。但是,為什么不能定義成public?這似乎難以理解。因為定義成public,我們不就可以很方便地設(shè)置changed屬性的值嗎?為了弄清楚這個問題,我們還是看一下Observable里的相關(guān)的代碼:

  //……省略……
  public void notifyObservers(Object arg) {
  //……省略……
   for (int i = arrLocal.length-1; i>=0; i--)
    ((Observer)arrLocal[i]).update(this, arg);
  }
    
  這段代碼表達(dá)的意思是說找出所有已注冊的Observer,再逐個進(jìn)行“通知”,通過調(diào)用Observer#update(Observable,Object)方法進(jìn)行通知。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 民勤县| 宝清县| 辛集市| 茂名市| 通海县| 南涧| 罗田县| 棋牌| 南安市| 札达县| 霸州市| 鲜城| 屯留县| 保康县| 翁牛特旗| 京山县| 镇赉县| 南投县| 隆德县| 黄陵县| 化州市| 乌审旗| 梅州市| 兴城市| 磐安县| 宕昌县| 鹤岗市| 内乡县| 衡阳市| 灵台县| 青神县| 遵义市| 乐昌市| 荔浦县| 新建县| 阜平县| 阿坝县| 清涧县| 文化| 肥西县| 齐河县|