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

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

探討與比較Java和.NET的事件處理框架

2019-11-18 11:12:40
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

事件驅(qū)動(dòng)模型

  事件驅(qū)動(dòng)模型是軟件系統(tǒng)平臺(tái)中的一個(gè)重要區(qū)域,現(xiàn)代軟件系統(tǒng)大量地使用事件驅(qū)動(dòng)的處理方法,尤其在用戶界面方面。雖然如此,過(guò)去在軟件開發(fā)語(yǔ)言中一直沒有融入事件處理的因子,直到.net的出現(xiàn),才將事件處理的工作負(fù)荷一部分的分派給編譯器,從而稍微減輕開發(fā)者的負(fù)擔(dān)。

  下圖顯示事件模型的組成份子:

探討與比較Java和.NET的事件處理框架(圖一)
(點(diǎn)擊查看原圖)
  Subscriber需事先和publisher預(yù)訂要接受其發(fā)布的某事件(下圖a1),publisher在某事件發(fā)生以后,必需先生成該事件的相關(guān)數(shù)據(jù)對(duì)象(下圖a2.1),然后通過(guò)方法調(diào)用來(lái)通知subscriber(下圖a2.2),也就是用回調(diào)(callback)的方式來(lái)通知subscriber。當(dāng)然在預(yù)訂的時(shí)候,并不一定要由subscriber自身來(lái)預(yù)訂,也可以由另一個(gè)對(duì)象來(lái)幫忙預(yù)訂。其動(dòng)態(tài)圖形示意如下:

探討與比較Java和.NET的事件處理框架(圖二)
(點(diǎn)擊查看原圖)
  本文并不探討異步的信息傳送,也就是在整個(gè)事件的處理過(guò)程當(dāng)中,publisher和subscriber 對(duì)象皆需要同時(shí)存在。假如對(duì)于離線(offline)的方式來(lái)處理事件有愛好的話,請(qǐng)參閱java的JMS(Java Message Service)和.NET的LCE(Loosely Coupled Events)。

  事件是什么?

  那么,到底事件是什么?在軟件系統(tǒng)中要如何表達(dá)一個(gè)事件?一個(gè)事件應(yīng)該包括兩個(gè)東西:識(shí)別事件的名稱(event identity),和事件的相關(guān)的數(shù)據(jù)(event data)。例如,一個(gè)鍵盤按鍵被按下的事件可能叫KeyPRessedEvent,事件數(shù)據(jù)則為該按鍵的代碼。

  先前提到發(fā)布事件是用調(diào)用方法的方式(回調(diào)),不過(guò)有一個(gè)問題,就是publisher無(wú)法事先知道subscriber的類型。在Java的編碼模式當(dāng)中,回調(diào)可以使用接口模式,也就是publisher必需事先定義好一個(gè)在發(fā)布事件中使用的接口,subscriber實(shí)現(xiàn)該接口中的方法,publisher則通過(guò)調(diào)用接口中的方法來(lái)完成發(fā)布事件的工作。如下圖:

探討與比較Java和.NET的事件處理框架(圖三)
(點(diǎn)擊查看原圖)
  這樣,在Java的編碼模式中,一個(gè)事件的識(shí)別名稱就是接口名稱和其中的方法名稱,而事件數(shù)據(jù)則自然是接口方法的參數(shù)了。Java對(duì)于這個(gè)接口的命名風(fēng)格為XXXListener,顧名思義就是某事件的傾聽者。例如:

public interface KeyListener extends EventListener {
 public void keyTyped(KeyEvent e);
 public void keyPressed(KeyEvent e);
 public void keyReleased(KeyEvent e);
}

  由于一個(gè)接口中可以包含多個(gè)方法,所以Java在設(shè)計(jì)事件的時(shí)候,是將一組相關(guān)聯(lián)的事件放在一起,這樣設(shè)計(jì)的優(yōu)點(diǎn)是可以很好的將事件做分類,并且在publisher中假如要處理的事件較多的話,可以使用比較少的成員變量來(lái)記錄subscribers。缺點(diǎn)是假如subscriber只對(duì)事件接口中的部分事件有愛好,也必需要全盤實(shí)現(xiàn)該接口(所以在AWT里有java.awt.event.XXXAdapter抽象輔助類)。另一個(gè)缺點(diǎn)則是必需要為每一類事件定義一個(gè)接口類型,即使可能大部分的事件只有極少的方法。

  微軟在為C#語(yǔ)言命名的時(shí)候,就刻意隱喻C#是從C/C++為基礎(chǔ)發(fā)展而得的面向?qū)ο蟪绦蛘Z(yǔ)言,始祖絕不是Java,所以肯定要保留一些C/C++的語(yǔ)言機(jī)制。在C/C++里面對(duì)回調(diào)的設(shè)計(jì)方式就是用函數(shù)指針,想當(dāng)然C#也希望直接使用類似函數(shù)調(diào)用的方式來(lái)做為事件發(fā)布的方法。如下圖:

探討與比較Java和.NET的事件處理框架(圖四)
(點(diǎn)擊查看原圖)
  所以C#期望使用函數(shù)指針類型來(lái)作為事件的識(shí)別名稱,然后用函數(shù)的參數(shù)來(lái)傳遞事件數(shù)據(jù)。我們先用一段C++代碼來(lái)描繪這幅圖畫:

Event type definition:
// 定義KeyPressedCallback 為一個(gè)函數(shù)指針的類型,
// 該函數(shù)接受一個(gè)整數(shù)型參數(shù),無(wú)返回值
typedef void (*KeyPressedCallback)(int keyCode);

Publisher:
class Publisher
{
 public KeyPressedCallback KeyPressedSink = null;
 ...
 void FireEvent(int KeyCode)
 {
  if (KeyPressedSink != null)
  (*KeyPressedSink)(keyCode);//callback
 }
}

Subscriber:
void KeyPressedHandler(int keyCode)
{
 ...
}
...
Publisher publisher = new Publisher();
//reGISter
publisher.KeyPressedSink = &KeyPressedHandler;

  一個(gè)當(dāng)代的純面向?qū)ο蟪绦蛘Z(yǔ)言,是肯定希望要把造成程序復(fù)雜和不易維護(hù)的指針給去除的。所以在C#語(yǔ)言機(jī)制當(dāng)中,勢(shì)必要?jiǎng)?chuàng)造新的元素來(lái)取代,于是delegate(委托)出現(xiàn)了。如下:

Event type definition:

// 定義KeyPressedDelegate 為一個(gè)類似函數(shù)指針的類型,
// 該函數(shù)接受一個(gè)整數(shù)型參數(shù),無(wú)返回值
delegate void KeyPressedDelegate(int keyCode);

Publisher:
class Publisher
{
 public KeyPressedDelegate KeyPressed = null;
 ...
 void FireEvent(int KeyCode)
 {
  if (KeyPressed != null)
   KeyPressed(keyCode);
 }
}

Subscriber:
void KeyPressedHandler(int keyCode)
{
 ...
}
...
Publisher publisher = new Publisher();
//register
publisher.KeyPressed = KeyPressedHandler;

  一開始,你可以把KeyPressedDelegate當(dāng)成是與函數(shù)指針相類似的東西,通過(guò)它你可以引用一個(gè)實(shí)例方法或靜態(tài)方法,就似乎引用一個(gè)對(duì)象一樣。然后可以通過(guò)這個(gè)delegate直接調(diào)用其引用的方法。但是下面你會(huì)看到delegate更擴(kuò)大了其引用能力。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 衡山县| 乌什县| 伊通| 元阳县| 达拉特旗| 吴川市| 东乌珠穆沁旗| 漯河市| 大城县| 沁水县| 车致| 多伦县| 新安县| 措勤县| 唐海县| 建湖县| 峨眉山市| 介休市| 治多县| 许昌市| 江源县| 科技| 墨江| 阿坝县| 平山县| 桂林市| 前郭尔| 苏尼特左旗| 雷山县| 通城县| 平泉县| 滁州市| 兴文县| 延安市| 托克逊县| 伊吾县| 莒南县| 延庆县| 逊克县| 洪洞县| 龙山县|