深入淺出話窗體(一) 窗體事件模型(上)

2021-04-16 14:33:09 字數 3176 閱讀 4413

深入淺出話窗體(一)

——窗體事件模型(上)

劉鐵猛

小序:

工作中最大的挑戰並不是那些mission impossible,而是你需要一邊保持安靜、平衡的心態以專注於工作,一邊對抗公司體制、社會經濟和人際環境對這種心態的破壞——這是對兒永遠也解不開的矛盾。

正文:

記得我在前面一篇文章裡提到過:壘磚頭壘多少年也成不了建築師——仍然只會砌牆。同樣,堆控制項堆多少年也成不了程式設計師——仍然只會拼湊窗體。成為建築師的關鍵在於學習建築的結構,成為程式設計師的關鍵則在於了解程式的結構。今天,就讓我們告別在窗體上堆控制項,剖析一下窗體與窗體上控制項關係——特別是事件的由來以及事件激發(event fire)與事件響應(event handling)之間的聯絡。

事件的由來

傳統的物件導向概念中是沒有事件(event)這個東西的,有的只是值域(field)和方法(method)。那麼事件又是怎麼來的呢?在傳統的物件導向程式設計中,如果乙個類想呼叫另乙個類的方法,程式設計師有兩種方法:

1.在乙個類的方法裡通過另乙個類的方法名進行直接呼叫,看上去會是這樣:

#include 

<

iostream

>

classa};

classb};

intmain(

intargc, 

char

*argv)

這樣做的好處在於程式結構相當簡單,但為這種「簡單」所付出的代價就是——類與類之間耦合過於緊密,而使程式幾乎不具有彈性和可伸縮性——於是有了另一種方法。

2.在主調類裡保有乙個函式指標,並將這個指標指向乙個函式,在這個函式裡再呼叫其它類的方法。喔~~~你可能會問:「幹嗎不讓這個指標直接指向其它類的方法,還要再借助乙個中間函式做跳板呢?」呵呵,答案是:函式指標是不能指向類的成員函式的——《c++必知必會》裡有詳細解釋,如果想再深挖一些,還可以看《深入探索c++物件模型》。這也就是我們常說的「間接引用」或者聞名遐邇的「**函式」啦:d 大概的樣子如下:

#include 

<

iostream

>

classa};

typedef 

void(*

functionpointer)();          

//把函式指標定義成一種「型別」

classb};

void

function()                                            

//將被間接呼叫的函式

intmain(

intargc, 

char

*argv)

這個模型真的非常不錯!而且在c/c++世界廣為流傳。然而,時過境遷,隨著.net時代的來臨和指標的不安全性(程式crash和記憶體洩漏之母:p)日益為人詬病,c#最終放棄了指標——確切地講是「囚禁」了指標。雖然放棄了指標,但c#並沒有放棄這種通過間接呼叫而降低類間耦合度的模型。微軟是怎樣做到的呢?原來,微軟為.net framework新增了一種新的資料型別——委託(delegate)。

作為一種新的引用型資料型別,委託是一種類。既然是類,就沒辦法直接當作類的成員來使咯,所以能當作類成員來使用的只能是委託的例項(聽起來真的是廢話~~但很多初學的朋友就是在這裡卡殼)。作為類的成員,委託的例項用起來的確很像函式指標,所以,我不得不再糾正乙個流傳甚廣的謬誤——有人說委託是函式指標的公升級或委託是「超級函式指標」——實際上應該說委託的例項是函式指標的公升級、委託的例項是「超級函式指標」。

對於「超級函式指標」這個title,委託的例項是當之無愧的。它除了可以像函式指標那樣「掛接」乙個方法(函式被封裝在類裡之後就稱之為「方法」了)外,功能大大超越了函式指標,這體現在:

ok,被c#粉飾一新的間接呼叫模型看上去會是這樣: //

= 《水之真諦》

=出品,

//宣告委託這種類的方法與宣告常規類不太一樣

//它看上去更像是在宣告「乙個函式指標」,這也正是我上面說的混淆之源。

//從語義上講,這句與上面c++**中使用typedef把函式指標定義為一種型別是一致的

classa!

", name);}}

classb}

}class

program

static

void

main(

string

args)

}

你可能會問:幹嗎不把委託設計成與a的method方法型別一致、再到b類中宣告乙個例項呢?這樣不就可以拋開那個什麼「當作跳板的函式」、直接呼叫a類例項的method方法了嗎?

主意不錯!但請你考慮這樣乙個問題:根據客戶需求和業務邏輯的需要,a類可能具有幾百個引數和返回值型別千奇百怪的方法,那麼,你打算專門針對a類開發出幾百種委託型別嗎?就算你開發出來了,b類的設計人員就樂意為b類宣告上如此一大摞專門針對a類的委託例項嗎?如果建立b類的程式設計師接納了針對a類的幾百個委託,那麼從針對c到z這些類的委託呢——要不要也接納進來?不接納——除非a和b是兩口子;接納——那b類的**長度估計不會低於央視大樓!況且,a類、b類以及其它類的設計人員可能根本就不在乙個公司、不在一起工作,怎麼可能「串通」起來做這種把類耦合在一起的浩大工程呢:p

說了半天光說委託了,事件呢?其實,事件是微軟對委託這個概念的進一步公升級。就**而言,事件僅僅是在委託的基礎上向前邁進了一小步,但是從程式邏輯的角度上觀察,事件卻是在思想上向前邁進了一大步!為什麼這樣講呢?且聽下回分解。

to be continue

法律宣告:csdn劉鐵猛

),並向[email protected]

深入淺出話窗體(一) 窗體事件模型(上)

深入淺出話窗體 一 窗體事件模型 上 劉鐵猛 小序 工作中最大的挑戰並不是那些mission impossible,而是你需要一邊保持安靜 平衡的心態以專注於工作,一邊對抗公司體制 社會經濟和人際環境對這種心態的破壞 這是對兒永遠也解不開的矛盾。正文 記得我在前面一篇文章裡提到過 壘磚頭壘多少年也成...

深入淺出話窗體(一) 窗體事件模型(上)

深入淺出話窗體 一 窗體事件模型 上 劉鐵猛 小序 工作中最大的挑戰並不是那些mission impossible,而是你需要一邊保持安靜 平衡的心態以專注於工作,一邊對抗公司體制 社會經濟和人際環境對這種心態的破壞 這是對兒永遠也解不開的矛盾。正文 記得我在前面一篇文章裡提到過 壘磚頭壘多少年也成...

深入淺出話窗體(一) 窗體事件模型(上)

深入淺出話窗體 一 窗體事件模型 上 劉鐵猛 小序 工作中最大的挑戰並不是那些mission impossible,而是你需要一邊保持安靜 平衡的心態以專注於工作,一邊對抗公司體制 社會經濟和人際環境對這種心態的破壞 這是對兒永遠也解不開的矛盾。正文 記得我在前面一篇文章裡提到過 壘磚頭壘多少年也成...