1. 程式人生 > >Java模式開發之責任鏈模式

Java模式開發之責任鏈模式

從擊鼓傳花談起

  擊鼓傳花是一種熱鬧而又緊張的飲酒遊戲。在酒宴上賓客依次坐定位置,由一人擊鼓,擊鼓的地方與傳花的地方是分開的,以示公正。開始擊鼓時,花束就開始依次傳遞,鼓聲一落,如果花束在某人手中,則該人就得飲酒。

  假比說,賈母、賈赦、賈政、賈寶玉和賈環是五個參加擊鼓傳花遊戲的傳花者,他們組成一個環鏈。擊鼓者將花傳給賈母,開始傳花遊戲。花由賈母傳給賈赦,由賈赦傳給賈政,由賈政傳給賈寶玉,又由賈寶玉傳給賈環,由賈環傳回給賈母,如此往復(見下圖)。當鼓聲停止時,手中有花的人就得執行酒令。


圖1、擊鼓傳花。

  擊鼓傳花便是責任鏈模式的應用。在責任鏈模式裡,很多的物件由每一個物件對其下家的引用而聯接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個物件決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪一個物件最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織鏈和分配責任。

  責任鏈可能是一條直線、一個環鏈甚至一個樹結構的一部分。

  責任鏈模式的結構


  責任鏈模式是一種物件的行為模式,它所涉及到的角色如下:

  第一、抽象處理者(Handler)角色、定義出一個處理請求的介面;如果需要,介面可以定義出一個方法,以返回對下家的引用。下圖給出了一個示意性的類圖:


圖2、抽象處理者角色。

  在圖中的積累關係給出了具體子類對下家的引用,抽象方法handleRequest()規範了子類處理請求的操作。

  第二、具體處理者(ConcreteHandler)角色、處理接到請求後,可以選擇將請求處理掉,或者將請 求傳給下家。下圖給出了一個示意性的類圖。


圖3、具體處理者角色。


  上圖中的示意性的具體處理者ConcreteHandler類只有handleRequest()一個方法。

  責任鏈模式的靜態類結構可見下圖:  



圖4、責任鏈模式的類圖定義。

  在圖中還給出了一個客戶端,以便讀者可以更清楚地看到責任鏈模式是怎樣應用的。抽象處理者的示意性原始碼:

public class Handler
 {
  public void handleRequest()
   {
    if (successor != null)
     {
       successor.handleRequest();
      }
     // Write your code here
    }
  public void setSuccessor(Handler successor)
    {
     this.successor = successor;
    }
  public Handler getSuccessor()
   {
    return successor;
   }
  private Handler successor;
  }
  程式碼清單1、抽象處理者的原始碼。

  具體處理者的示意性原始碼:

public class ConcreteHandler extends Handler
  {
   public void handleRequest()
    {
     if (getSuccessor() != null)
     {
      getSuccessor().handleRequest();
     }
     if (successor != null)
     {
      successor.handleRequest();
     }
    // Write your code here
    }
  }
  程式碼清單2、具體處理者的原始碼。

  客戶端的原始碼如下:

public class Client
  {
   private Handler handler;
   public static void main(String[] args)
    {
     handler = new ConcreteHandler();
     //write your code here
    }
  }


  程式碼清單3、客戶端的原始碼

純的與不純的責任鏈模式

  一個純的責任鏈模式要求一個具體的處理者物件只能在兩個行為中選擇一個:一是承擔責任,二是把責任推給下家。不允許出現某一個具體處理者物件在承擔了一部分責任後又把責任向下傳的情況。

  在一個純的責任鏈模式裡面,一個請求必須被某一個處理者物件所接受;在一個不純的責任鏈模式裡面,一個請求可以最終不被任何接受端物件所接受。

  純的責任鏈模式的實際例子很難找到,一般看到的例子均是不純的責任鏈模式的實現。有些人認為不純的責任鏈根本不是責任鏈模式,這也許是有道理的;但是在實際的系統裡,純的責任鏈很難找到;如果堅持責任鏈不純便不是責任鏈模式,那麼責任鏈模式便不會有太大的意義了。

  Java1.0版的AWT事件處理機制

  Java的1.0版中AWT庫使用了責任鏈模式和命令模式來處理GUI的事件。由於視窗部件往往處在容器部件裡面,因此當事件發生在一個部件上時,此部件的事件處理器可以處理此事件,然後決定是否將事件向上級容器部件傳播;上級容器部件接到事件後可以在此處理此事件然後決定是否將事件再次向上級容器部件傳播,如此往復,直到事件到達頂層部件。

  事件浮升機制

  比如,當一個視窗部件接到一個MOUSE_CLICKED事件時,事件首先傳播到它所發生的部件上,然後向其容器部件傳播。容器可以選擇處理這個事件,或者再將此事件向更高一級的容器部件傳播。事件如此一級級地向上傳播,就像水底的氣泡一點一點地冒到水面上一樣,因此又叫做事件浮升(Event Bubbling)機制。下面就是一段典型的Java1.0版的AWT庫裡處理事件的程式碼:

public boolean action(Event event, Object obj)
  {
    if (event.target == btnOK)
     {
      doOKBtnAction();
     }
    else if (event.target == btnExit)
     {
      doExitBtnAction();
     }
    else
     {
      return super.action(event, obj);
     }
    return true;
  }

程式碼清單4、Java1.0版本中AWT處理事件的典型程式碼。

  在這段程式碼裡面,action()判斷目標部件是不是btnOK或btnExit;如果是,便執行相應的方法;如果不是,便返還true。一個方法返還true便使得事件停止浮升。

  AWT1.0的事件處理的模型的缺點之一

  AWT1.0的事件處理的模型是基於繼承的。為了使一個程式能夠捕捉GUI的事件並處理此事件,必須subclass此部件並且給其子類配備事件處理器,也就是置換掉action()方法或者handleEvent()方法。這不是應當提倡的做法:在一個面向物件的系統裡,經常使用的應當是委派,繼承不應當是常態。

  在一個複雜的GUI系統裡,這樣為所有有事件的部件提供子類,會導致很多的子類,這是不是很麻煩的嗎?

  當然,由於事件浮升機制,可以在部件的樹結構的根部部件裡面處理所有的事件。但是這樣一來,就需要使用複雜的條件轉移語句在這個根部部件裡辨別事件的起源和處理方法。這種非常過程化的處理方法很難維護,並且與面向物件的設計思想相違背。

  AWT1.0的事件處理的模型的缺點之二

  由於每一個事件都會沿著部件樹結構向上傳播,因此事件浮升機制會使得事件的處理變得較慢。這也是缺點之一。

  比如在有些作業系統中,滑鼠每移動一個色素,都會激發一個MOUSE_MOVE事件。每一個這樣的事件都會沿著部件的容器樹結構向上傳播,這會使得滑鼠事件成災。

  AWT1.0的事件處理的模型的缺點之三

  AWT1.0的事件處理的模型只適用於AWT部件類。這是此模型的另一個缺點。

  責任鏈模式要求鏈上所有的物件都繼承自一個共同的父類,這個類便是java.awt.Component類。

  AWT1.0的事件處理的模型是不純的責任鏈模式

  顯然,由於每一級的部件在接到事件時,都可以處理此事件;而不論此事件是否在這一級得到處理,事件都可以停止向上傳播或者繼續向上傳播。這是典型的不純的責任鏈模式。

  AWT1.1以後的事件處理的模型

  自從AWT1.1以後,AWT的事件處理模型於1.0相比有了很大的變化。新的事件處理模型是建立在觀察者模式的基礎之上的,而不再是責任鏈模式的基礎之上的。

  關於新的事件處理模型和觀察者設計模式,請見“觀察者模式”一節.

紅樓夢中擊鼓傳花的故事

  顯然,擊鼓傳花符合責任鏈模式的定義。參加遊戲的人是一個個的具體處理者物件,擊鼓的人便是客戶端物件。花代表酒令,是傳向處理者的請求,每一個參加遊戲的人在接到傳來的花時,可選擇的行為只有兩個:一是將花向下傳;一是執行酒令---喝酒。一個人不能既執行酒令,又向下家傳花;當某一個人執行了酒令之後,遊戲重新開始。擊鼓的人並不知道最終是由哪一個做遊戲的人執行酒令,當然執行酒令的人必然是做遊戲的人們中的一個。

  擊鼓傳花的類圖結構如下:



圖5、擊鼓傳花系統的類圖定義。

  單獨考慮擊鼓傳花系統,那麼像賈母、賈赦、賈政、賈寶玉和賈環等傳花者均應當是“具體傳花者”的物件,而不應當是單獨的類;但是責任鏈模式往往是建立在現有系統的基礎之上的,因此鏈的結構和組成不由責任鏈模式本身決定。

  系統的分析

  在《紅樓夢》第七十五回裡生動地描述了賈府裡的一場擊鼓傳花遊戲:“賈母坐下,左垂首賈赦,賈珍,賈璉,賈蓉,右垂首賈政,寶玉,賈環,賈蘭,團團圍坐。...賈母便命折一枝桂花來,命一媳婦在屏後擊鼓傳花。若花到誰手中,飲酒一杯...於是先從賈母起,次賈赦,一一接過。鼓聲兩轉,恰恰在賈政手中住了,只得飲了酒。”這場遊戲接著又把花傳到了寶玉和賈赦手裡,接著又傳到了在賈環手裡...

  如果用一個物件系統描述賈府,那麼賈母、賈赦、賈政、賈寶玉和賈環等等就應當分別由一個個具體類代表,而這場擊鼓傳花遊戲的類圖,按照責任鏈模式,應當如下圖所示:



圖6、紅樓夢中的擊鼓傳花遊戲的示意性類圖。

  換言之,在擊鼓傳花遊戲裡面,有下面的幾種角色:

  •  抽象傳花者,或Handler角色、定義出參加遊戲的傳花人要遵守的規則,也就是一個處理請求的介面 和對下家的引用;

  •  具體傳花者,或ConcreteHandler角色、每一個傳花者都知道下家是誰,要麼執行酒令,要麼把花 向下傳。這個角色由賈母、賈赦、賈珍、賈璉、賈蓉、賈政、寶玉、賈環、賈蘭等扮演。

  •  擊鼓人,或Client角色、即行酒令的擊鼓之人。《紅樓夢》沒有給出此人的具體姓名,只是說由“一 媳婦”扮演。




圖7、賈府這次擊鼓傳花的示意性物件圖。

  可以看出,擊鼓傳花遊戲滿足責任鏈模式的定義,是純的責任鏈模式的例子.

Java系統的解  下面的類圖給出了這些類的具體介面設計。讀者不難看出,DrumBeater(擊鼓者)、Player(傳花者)、JiaMu(賈母)、JiaShe(賈赦)、JiaZheng(賈政)、JiaBaoYu(寶玉)、JiaHuan(賈環)等組成這個系統。



圖8、擊鼓傳花的類圖完全符合責任鏈模式的定義。

  下面是客戶端類DrumBeater的原始碼:

public class DrumBeater
{
  private static Player player;
  static public void main(String[] args)
   {
    player = new JiaMu( new JiaShe( new JiaZheng( new JiaBaoYu(new JiaHuan(null)))));
    player.handle(4);
   }
}

  程式碼清單5、DrumBeater的原始碼。

abstract class Player
{
  abstract public void handle(int i);
  private Player successor;
  public Player() { successor = null;
}
protected void setSuccessor(Player aSuccessor)
{
  successor = aSuccessor;
}
public void next(int index)
{
  if( successor != null )
   {
    successor.handle(index);
   }
  else
   {
    System.out.println("Program terminated.");
   }
  }
}

  程式碼清單6、抽象傳花者Play類的原始碼。

  抽象類Player給出了兩個方法的實現,以格式setSuccessor(),另一個是next()。前者用來設定一個傳花者物件的下家,後者用來將酒令傳給下家。Player類給出了一個抽象方法handle(),代表執行酒令。

  下面的這些具體傳花者類將給出handle()方法的實現。

class JiaMu extends Player
  {
   public JiaMu(Player aSuccessor)
   {
    this.setSuccessor(aSuccessor);
   }
   public void handle(int i)
   {
    if( i == 1 )
    {
     System.out.println("Jia Mu gotta drink!");
    }
    else
    {
     System.out.println("Jia Mu passed!"); next(i);
    }
   }
  }

  程式碼清單7、代表賈母的JiaMu類的原始碼。

class JiaShe extends Player
  {
   public JiaShe(Player aSuccessor)
   {
    this.setSuccessor(aSuccessor);
   }
   public void handle(int i)
    {
     if( i == 2 )
     {
      System.out.println("Jia She gotta drink!");
     }
     else
     {
      System.out.println("Jia She passed!");
      next(i);
     }
    }
  }

  程式碼清單8、代表賈赦的JiaShe類的原始碼。

class JiaZheng extends Player
  {
   public JiaZheng(Player aSuccessor)
   {
    this.setSuccessor(aSuccessor);
   }
   public void handle(int i)
   {
    if( i == 3 )
    {
     System.out.println("Jia Zheng gotta drink!");
    }
    else
    {
     System.out.println("Jia Zheng passed!");
     next(i);
    }
   }
  }

  程式碼清單9、代表賈政的JiaZheng類的原始碼。

class JiaBaoYu extends Player
  {
   public JiaBaoYu(Player aSuccessor)
   {
    this.setSuccessor(aSuccessor);
   }
   public void handle(int i)
   {
    if( i == 4 )
    {
     System.out.println("Jia Bao Yu gotta drink!");
    }
    else
    {
     System.out.println("Jia Bao Yu passed!");
     next(i);
    }
   }
  }

  程式碼清單10、代表賈寶玉的JiaBaoYu類的原始碼。

class JiaHuan extends Player
  {
   public JiaHuan(Player aSuccessor)
    {
     this.setSuccessor(aSuccessor);
    }
   public void handle(int i)
   {
    if( i == 5 )
    {
     System.out.println("Jia Huan gotta drink!");
    }
    else
    {
     System.out.println("Jia Huan passed!");
     next(i);
    }
   }
  }

  程式碼清單11、代表賈環的JiaHuan類的原始碼。

  可以看出,DrumBeater設定了責任鏈的成員和他們的順序:責任鏈由賈母開始到賈環,周而復始。JiaMu類、JiaShe類、JiaZheng類、JiaBaoYu類與JiaHuan類均是抽象傳花者Player類的子類。

  本節所實現的DrumBeater類在把請求傳給賈母時,實際上指定了由4號傳花者處理酒令。雖然DrumBeater並不知道哪一個傳花者類持有號碼4,但是這個號碼在本系統一開始就寫死的。這當然並不符合擊鼓傳花遊戲的精神,因為這個遊戲實際上要求有兩個同時進行的過程:擊鼓過程和傳花過程。擊鼓應當是定時停止的,當擊鼓停止時,執行酒令者就確定了。但是本節這樣做可以使問題得到簡化並將讀者的精力放在責任鏈模式上,而不是兩個過程的處理上。

  下一章會給出一個多執行緒的系統,更加逼真地模擬擊鼓傳花系統。

在什麼情況下使用責任鏈模式

  在下面的情況下使用責任鏈模式:

  第一、系統已經有一個由處理者物件組成的鏈。這個鏈可能由複合模式給出,

  第一、當有多於一個的處理者物件會處理一個請求,而且在事先並不知道到底由哪一個處理者物件處理一個請求。這個處理者物件是動態確定的。

  第二、當系統想發出一個請求給多個處理者物件中的某一個,但是不明顯指定是哪一個處理者物件會處理此請求。

  第三、當處理一個請求的處理者物件集合需要動態地指定時。

  使用責任鏈模式的長處和短處

  責任鏈模式減低了發出命令的物件和處理命令的物件之間的耦合,它允許多與一個的處理者物件根據自己的邏輯來決定哪一個處理者最終處理這個命令。換言之,發出命令的物件只是把命令傳給鏈結構的起始者,而不需要知道到底是鏈上的哪一個節點處理了這個命令。

  顯然,這意味著在處理命令上,允許系統有更多的靈活性。哪一個物件最終處理一個命令可以因為由那些物件參加責任鏈、以及這些物件在責任鏈上的位置不同而有所不同。

  責任鏈模式的實現

  鏈結構的由來

  值得指出的是,責任鏈模式並不創建出責任鏈。責任鏈的建立必須有系統的其它部分完成。

  責任鏈模式減低了請求的傳送端和接收端之間的耦合,使多個物件都有機會處理這個請求。一個鏈可以是一條線,一個樹,也可以是一個環。鏈的拓撲結構可以是單連通的或多連通的,責任鏈模式並不指定責任鏈的拓撲結構。但是責任鏈模式要求在同一個時間裡,命令只可以被傳給一個下家(或被處理掉);而不可以傳給多於一個下家。在下面的圖中,責任鏈是一個樹結構的一部分。



圖9、責任鏈是系統已有的樹結構的一部分。圖中有陰影的物件給出了一個可能的命令傳播路徑。

  責任鏈的成員往往是一個更大的結構的一部分。比如在前面所討論的《紅樓夢》中擊鼓傳花的遊戲中,所有的成員都是賈府的成員。如果責任鏈的成員不存在,那麼為了使用責任鏈模式,就必須建立它們;責任鏈的具體處理者物件可以是同一個具體處理者類的例項。

  在Java的1.0版的AWT事件處理模型裡,責任鏈便是視窗上的部件的容器等級結構。

  在下面會談到的Internet Explorer的DHTML的DOM事件處理模型裡,責任鏈則是DOM等級結構本身。

  命令的傳遞

  在一個責任鏈上傳遞的可能不只有一個命令,而是數個命令。這些命令可以採取抽象化層、具體化層的多型性實現方式,見下圖,從而可以將命令物件與責任鏈上的物件之間的責任分隔開,並將命令物件與傳播命令的物件分隔開。



圖10、多個命令在責任鏈上的傳播。

  當然如果責任鏈上的傳播的命令只有一個、且是固定的命令,那麼這個命令不一定要物件化。這就是本節處理擊鼓傳花遊戲裡面傳來傳去的花束的辦法。花束代表酒令,可以由一個物件代表;但是本章的處理是過程式的,用對下家物件的next()方法的呼叫達成。

物件的樹結構

  在面嚮物件的技術裡,物件的樹結構是一個強有力的工具,更是模式理論的一個重要的組成部分,需要應用到符合模式、裝飾模式和迭代子模式。

  《墨子.天志》說:“庶人竭力從事,未得次己而為政,有士政之,士竭力從事,未得次己而為政,有將軍、大夫政之;將軍、大夫竭力從事,未得次己而為政,有三公、諸侯政之;三公、諸侯竭力聽治,未得次己而為政,有天子政之;天子未得次己而為政,有天政之。”

  “次”意為恣意。上面的話就是說,百姓有官吏管治,官吏由將軍和士大夫管治,將軍和士大夫由三公和諸侯管治,三公和諸侯由天子管治,天子由天管治。



圖11、墨子論責任和責任鏈的傳播。圖中有陰影的物件給出了一個可能的責任鏈選擇。

  當一個百姓提出要求時,此要求會傳達到“士”一級,再到“大夫”一級,進而傳到“諸侯”一級,“天子”一級,最後到“天”一級.

DHTML中的事件處理瀏覽器的DOMDocument Object Model)模型中的事件處理均採用責任鏈模式。本節首先考察Netscape瀏覽器的DHTML的事件處理,然後再研究Internet Explorer的事件模型。Netscape的事件模型Netscape的事件處理機制叫做“事件捕捉”(Event Capturing)。在事件捕捉機制裡面,一個事件是從DOM的最高一層向下傳播,也就是說,window物件是第一個接到事件的,然後是document物件,如此往下---事件的產生物件反而是最後一個接到事件的。  如果要是一個物件捕獲某一個事件,只需要呼叫captureEvent()方法;如果要使一個物件把某一個事件向下傳而不處理此事件,只需要對此物件使用releaseEvents方法即可。下面考察一個簡單的事件捕獲和傳遞的例子。12、一個Netscape的例子。  在這個例子裡,有一個textbox和兩個button,一個叫做“Capture Event”,單擊後會使網頁的click事件被捕捉,文字框中的計數會加一;另一個叫做“Release Event”,單擊後會使網頁的click事件不被捕捉。  使click事件被捕捉需要呼叫captureEvent()方法,而使click事件不被捕捉需要呼叫releaseEvent()方法。下面是具體的htmlJavaScript程式碼。

程式碼清單6JavaScriptHTML原始碼。  顯然,一個事件可以在幾個不同的等級上得到處理,這是一個不純的責任鏈模式。Internet Explorer的事件模型Internet Explorer處理事件的方式與Netscape既相似又不同。當一個事件發生在Internet Explorer所瀏覽的網頁中時,Internet Explorer會使用DHTML的“Event Bubbling”即事件浮升機制處理此事件。Internet ExplorerDOM模型是html物件等級結構和事件處理機制。在DOM裡面,每一個html標示都是一個DOM物件,而每一個DOM物件都可以產生事先定義好的幾個事件中的一個(或幾個)。這樣的一個事件會首先發生在事件所屬的物件上,然後向上傳播,傳到此物件所屬的容器物件上,如此等等。因此,事件浮升機制恰恰是事件捕捉機制的相反面。Event Bubbling機制裡面,產生事件的物件首先會收到事件。然後,事件會依照物件的等級結構向上傳播。比如一個DIV裡有一個FormForm裡面又有一個Button,那麼當Buttononclick事件產生時,Formonclick事件程式碼就會被執行。然後,事件就會傳到DIV物件。如果DIV物件的onclick事件有任何程式碼的話,這程式碼就會被執行,然後事件繼續沿著DOM結構上行。  如果要阻止事件繼續向上傳播,可以在事件鏈的任何一個節點上把cancelBubble性質設定成True即可。Internet Explorer 瀏覽器幾乎為所有的 HTML 識別符號都提供了事件控制代碼,因此Internet Explorer不需要captureEvents()方法和releaseEvents()方法來捕獲和釋放事件。下面的JavaScript語句指定了document物件的onclick事件的處理方法:

document.onclick = functionName;

  而下面的語句則停止了document物件對onclick事件的處理。

document.onclick = null;

  因為事件處理性質被賦值nulldocument便沒有任何的方法處理此事件。換言之,null值禁止了此物件的事件處理。這種方法可以用到任何的物件和任何的事件上面。當然這一做法不適用於Netscape  與Netscape中一樣,一個事件處理方法可以返還Boolean值。比如,單擊一個超連結標記符是否造成瀏覽器跟進,取決於此超連結標記符的onclick事件是否返還true  為了顯示Internet Explorer中的事件浮升機制,本節特准備了下面的例子。一個Form裡面有一個Button,請見下圖:13、一個Internet Explorer的例子。  其HTML程式碼請見下面:

程式碼清單7JavaScriptHTML原始碼。  當myButtononclick事件發生時,myButton的事件處理首先被激發,從而顯示出如下的對話窗:14myButton物件的事件處理被激發。  然後事件會象氣泡一樣浮升到上一級的物件,即myForm物件上。myForm物件的事件處理給出下面的對話窗:15myFormn物件的事件處理被激發。  這以後事件繼續浮升到更上一級的物件,即body上。這時,document物件的事件處理被激發,並給出下面的物件窗:16document物件的事件處理被激發。  這就是事件浮升(Event Bubbling)機制。  顯然,這三級物件組成一個責任鏈,而事件便是命令或請求。當事件沿著責任鏈傳播時,責任鏈上的物件可以選擇處理或不處理此事件;不論事件在某一個等級上是否得到處理,事件都可以停止上浮或繼續上浮。這是不純的責任鏈模式

DHTML中的事件處理瀏覽器的DOMDocument Object Model)模型中的事件處理均採用責任鏈模式。本節首先考察Netscape瀏覽器的DHTML的事件處理,然後再研究Internet Explorer的事件模型。Netscape的事件模型Netscape的事件處理機制叫做“事件捕捉”(Event Capturing)。在事件捕捉機制裡面,一個事件是從DOM的最高一層向下傳播,也就是說,window物件是第一個接到事件的,然後是document物件,如此往下---事件的產生物件反而是最後一個接到事件的。  如果要是一個物件捕獲某一個事件,只需要呼叫captureEvent()方法;如果要使一個物件把某一個事件向下傳而不處理此事件,只需要對此物件使用releaseEvents方法即可。下面考察一個簡單的事件捕獲和傳遞的例子。12、一個Netscape的例子。  在這個例子裡,有一個textbox和兩個button,一個叫做“Capture Event”,單擊後會使網頁的click事件被捕捉,文字框中的計數會加一;另一個叫做“Release Event”,單擊後會使網頁的click事件不被捕捉。  使click事件被捕捉需要呼叫captureEvent()方法,而使click事件不被捕捉需要呼叫releaseEvent()方法。下面是具體的htmlJavaScript程式碼。

程式碼清單6JavaScriptHTML原始碼。  顯然,一個事件可以在幾個不同的等級上得到處理,這是一個不純的責任鏈模式。Internet Explorer的事件模型Internet Explorer處理事件的方式與Netscape既相似又不同。當一個事件發生在Internet Explorer所瀏覽的網頁中時,Internet Explorer會使用DHTML的“Event Bubbling”即事件浮升機制處理此事件。Internet ExplorerDOM模型是html物件等級結構和事件處理機制。在DOM裡面,每一個html標示都是一個DOM物件,而每一個DOM物件都可以產生事先定義好的幾個事件中的一個(或幾個)。這樣的一個事件會首先發生在事件所屬的物件上,然後向上傳播,傳到此物件所屬的容器物件上,如此等等。因此,事件浮升機制恰恰是事件捕捉機制的相反面。Event Bubbling機制裡面,產生事件的物件首先會收到事件。然後,事件會依照物件的等級結構向上傳播。比如一個

相關推薦

Java模式開發責任模式

從擊鼓傳花談起  擊鼓傳花是一種熱鬧而又緊張的飲酒遊戲。在酒宴上賓客依次坐定位置,由一人擊鼓,擊鼓的地方與傳花的地方是分開的,以示公正。開始擊鼓時,花束就開始依次傳遞,鼓聲一落,如果花束在某人手中,則該人就得飲酒。  假比說,賈母、賈赦、賈政、賈寶玉和賈環是五個參加擊鼓傳花遊

JAVA模式責任模式

在閻巨集博士的《JAVA與模式》一書中開頭是這樣描述責任鏈(Chain of Responsibility)模式的:   責任鏈模式是一種物件的行為模式。在責任鏈模式裡,很多物件由每一個物件對其下家的引用而連線起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個物件決定

設計模式學習責任模式(Chain of Responsibility,行為型模式)(22)

分析 一定的 之間 ash 我們 set 抽象 request 發現 參考:http://www.cnblogs.com/zhili/p/ChainOfResponsibity.html 一、引言   在現實生活中,有很多請求並不是一個人說了就算的,例如面試時的工資,低

Java設計模式 責任模式

Java設計模式 - 責任鏈模式   責任鏈模式應用場景: 使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係.將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理它為止.適合使用責任鏈模式的情景如下:有許多物件可以處理使用者的請求,應用程式可以

java 設計模式責任模式的幾種寫法

寫法1: package com.huang.test.designmodel; /** * java 設計模式:責任鏈模式 */ public class ChainOfResponsibilityPatternTest { public static fi

Java設計模式責任模式、職責模式

什麼是鏈1、鏈是一系列節點的集合。2.、鏈的各節點可靈活拆分再重組。職責鏈模式使多個物件都有機會處理請求,從而避免請求的傳送者和接受者之間的耦合關係,將這個物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理他為止。角色抽象處理者角色(Handler):定義出一個處理請

java設計模式 責任(chain of resposibility)模式

  責任鏈模式,顧名思義,就是一條鏈。這個鏈到底是怎麼執行的呢?它主要是將能夠處理同一類請求的物件連成一條鏈,所提交的請求沿著鏈傳遞,鏈上的物件逐個判斷是否有能力處理該請求,如果能則處理,如果不能則

Java設計模式——責任模式

責任鏈模式簡單介紹 責任鏈模式,是行為性設計模式之一。什麼是“鏈”?我們將多個節點首尾相連構成的模型稱為鏈,比如生活中常見的鎖鏈,就是由一個個圓角長方形的鐵環串起來的結構。對於鏈式結構,每個節點都可以被拆開在連線,因此,鏈式結構也具有很好的靈活性。將這樣一種結

java設計模式責任模式、狀態模式、策略模式

若您對我的分享感興趣可以訪問:java設計模式專欄在常用的23中設計模式中,有三種模式容易混淆,這三種模式分別是:責任鏈模式、狀態模式以及策略模式因此接下來我們把這三種模式放在一起討論1、責任鏈模式(okHttp)職責鏈的本質是:不同的類對同一個問題的反應    責任鏈模式下

折騰Java設計模式責任模式

責任鏈模式 顧名思義,責任鏈模式(Chain of Responsibility Pattern)為請求建立了一個接收者物件的鏈。這種模式給予請求的型別,對請求的傳送者和接收者進行解耦。這種型別的設計模式屬於行為型模式。在這種模式中,通常每個接收者都包含對另一個接收者的引用。如果一個物件不能處理該請求

設計模式責任模式——Java語言描述

責任鏈模式為請求建立了一個接受者物件的鏈。這種模式給予請求的型別,對請求的傳送者和接受者進行解耦。這種型別的設計模式屬於行為模式。在這種模式下,通常每個接收者都包含對另一個接收者的引用。如果一個物件不能處理該物件,那麼它會把相同的請求傳給下一個接收者,以此類推 介紹 意圖 避免請求傳送者和接收

Java 設計模式責任模式

責任鏈模式(Chain of Responsibliity) 縮寫COR 該模式屬於物件的行為模式。多個物件連成一條鏈,請求沿著這條鏈進行傳遞,直到有一個物件處理它為止,這樣使得多個物件都有機會處理請求,從而避免了請求的傳送者和接收者之間的耦合關係。 責任鏈模式涉及到的角

Java模式責任模式

從請假開始談起 話說上次五一請假回去玩了一個多星期,期間回了一次老家,去了一趟武漢,接著又跑到了景德鎮,和廬山;玩的好不自在;但是想起來上次請假的經歷另我記憶猶新啊,算起來也是一波三折吧; 記得那時是4月20號,因為家裡出了點事情,急需回家,然後也快到五一了,就想出去玩幾天

淺談JAVA設計模式——責任模式(COR)

一、概述 使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係。將這些物件連成一條鏈, 並沿著這條鏈傳遞該請求,直到有一個物件處理它為止。 這一模式的想法是,給多個物件處理一個請求的機會,從而解耦傳送者和接受者. 二、適用性 1.有多個的物件可以處理一個

設計模式責任模式

設計模式 責任鏈模式 chain of responsibility 1、責任鏈模式 chainOfResponsiblity : a、責任鏈模式屬於行為型模式,行為型模式關註系統中對象之間的相互交互,研究系統在運行時對象之間的相互通信和協作,進一步明確對象的職責,共有11中模式。 b

設計模式責任模式 chainOfResp

span 設計 end days lap str spa pub none 後面我們將學習設計模式裏面的行為型模式 代碼實現 /** * 抽象類 * @author bzhx * 2017年3月14日 */ public abstract cla

Head First設計模式責任模式

sre apple ria tap 空調 href 一個 -o webkit 一、定義   避免請求發送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿著這條鏈傳遞請求,直到有對象處理它為止。   主要解決:職責鏈上的處理者負責處理請求,

一天學習一個設計模式責任模式

null public 接收 req sta and new get main 1 責任鏈模式(chain of Responsibility):使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這個對象連成一條鏈,並沿著這條鏈傳遞請求,直到有一個

設計模式漫談責任

st3 更新 運行 stc 動態 tap common 都是 string 這段時間談戀愛了,也就沒更新隨筆。後天就軟考了,不過我已經抱著失敗是成功他媽的準備了。做軟件不能急,要穩著性子做幾年再說,剛畢業的應屆生啥都想學,老想一口吃個胖子,沒有5年以上的工作經驗,就是再NB

php 設計模式責任模式

責任鏈模式1. 模式介紹 使多個物件都有機會處理請求,從而避免請求的傳送者和接受者之間的耦合關係,將這個物件連成一條鏈,並沿著這個鏈傳遞該請求,直到有一個物件處理它為止。2.模式組成  2.1 抽象處理者(Handler)角色:        定義出一個