細(xì)節(jié)決定成敗 ASP.NET中的蝴蝶效應(yīng)
2006/11/30 10:01:41
前言 

  ASP.NET的優(yōu)點(diǎn)我說(shuō)過(guò)很多次了,也就是各個(gè)控件獨(dú)立負(fù)責(zé)自己內(nèi)部的邏輯,這是一個(gè)好事情,因?yàn)樗鉀Q了原本ASP處理邏輯耦合度高的問(wèn)題。然而這是需要代價(jià)的,那就是引入ASP.NET頁(yè)面生命周期,隨著控件的多層嵌套,應(yīng)用的復(fù)雜度增加,我們?cè)俅蜗萑肽嗵?
  問(wèn)題
  其實(shí)這個(gè)文章題目我兩個(gè)月前就寫下了,可是一直沒(méi)想寫完它,直到今天我在這個(gè)泥潭中泡了幾個(gè)小時(shí),于是決定先從泥潭中跳出來(lái)把文章寫完,再跳進(jìn)去繼續(xù)解決問(wèn)題。問(wèn)題是這樣的:
  使用MS AJAX 1.0 Beta2 + 2.0 CTP新建一個(gè)項(xiàng)目,同時(shí)在Bin中放上Beta2的AjaxControlToolkit.dll。
  扔上一個(gè)Accordion,放置幾個(gè)AccordionPane,設(shè)置一下CssClass。
  在Page_Load中使用Page.LoadControl加載一個(gè)UserControl,然后添加到頁(yè)面上。
  接著發(fā)現(xiàn)UserControl內(nèi)的控件無(wú)法正常觸發(fā)事件,陷入泥潭中……
  首先要說(shuō)明,如果僅僅做第3步那個(gè)UserControl肯定正常運(yùn)作,那意味著問(wèn)題出在ScriptManager或Accordion中出現(xiàn)了問(wèn)題。
  正文
  想知道到底是什么出問(wèn)題了嗎?先聽(tīng)我說(shuō)說(shuō)這個(gè)ASP.NET頁(yè)面生命周期的問(wèn)題吧。
  由于生命周期按階段劃分,任務(wù)在不同階段按部就班完成,所以我們的每一個(gè)操作都是階段相關(guān)的,有些操作僅能在特定的階段操作,有些操作在不同階段執(zhí)行會(huì)導(dǎo)致不同的結(jié)果。當(dāng)然,MS希望盡量消除這些階段間的差異,例如讓一個(gè)操作在盡可能多的階段中都能執(zhí)行,并且盡可能減少在不同階段中操作引發(fā)的不同結(jié)果。然而這不可能完全做到,例如我們都知道ViewState讀寫限制為僅能在某些階段進(jìn)行,于是依賴于ViewState的控件屬性也就因此受到同樣的限制。
  控件屬性讀寫受階段限制,這很好接受,對(duì)吧?因?yàn)檫@僅僅是一層依賴關(guān)系。順著依賴關(guān)系推廣出去,情況會(huì)變得越來(lái)越復(fù)雜,限制的原因埋藏得越來(lái)越底層,接著我們發(fā)現(xiàn)復(fù)雜性這一問(wèn)題在ASP.NET這種結(jié)構(gòu)良好的體系中出現(xiàn)了,而消滅這種復(fù)雜性的銀彈還沒(méi)被發(fā)明。
  作為控件或組件的開(kāi)發(fā)人員,我們當(dāng)然有義務(wù)消除階段差異,讓下游的開(kāi)發(fā)人員面對(duì)更低的復(fù)雜性,而且我們也確實(shí)盡力去做了。控件的每一層封裝,都包含著這種努力,并向上承諾盡可能低的階段差異。然而為了讓控件看起來(lái)簡(jiǎn)單易用,我們不可能將這些差異完整地記錄在文檔之中,我們嘗試去隱瞞細(xì)節(jié),控件被層層封裝時(shí)我們都這樣做。底層文檔沒(méi)告訴我的差異,我當(dāng)然也沒(méi)必要寫到這一層的文檔上去;底層文檔提及了的差異,我盡力彌補(bǔ)了,即使彌補(bǔ)得不太好,也不寫到這一層的文檔上去。于是文檔就好像神話傳說(shuō)一樣隨著世代相傳而改變,最終沒(méi)有人知道這個(gè)控件依賴于某些底層的階段差異。
  做過(guò)控件開(kāi)發(fā)的人都知道,有時(shí)候我們必須根據(jù)實(shí)際情況采用不同的方式構(gòu)建看起來(lái)一樣的控件。例如最簡(jiǎn)單的數(shù)據(jù)控件都會(huì)存在是否PostBack的構(gòu)建差異,如果是非PostBack,則需要在DataBind時(shí)構(gòu)建并將數(shù)據(jù)保存到ViewState,如果是PostBack則根據(jù)ViewState直接構(gòu)建,如果PostBack后又遇到了DataBind則需要清除原來(lái)的構(gòu)建并重新根據(jù)新數(shù)據(jù)構(gòu)建。再?gòu)?fù)雜一些的控件,還會(huì)分步驟構(gòu)建,默認(rèn)情況下為了消除使用方的階段差異,部分構(gòu)建步驟會(huì)盡可能靠前到Init時(shí)執(zhí)行,而另外一部分構(gòu)建步驟則盡可能推遲到PreRender時(shí)執(zhí)行,中間部分則盡可能減少自己的變化以便使用方操作。然而事情不會(huì)那么簡(jiǎn)單,使用方的某些操作(通常是訪問(wèn)某個(gè)屬性)如果依賴于某個(gè)構(gòu)建步驟的完成,因此一旦這些操作出現(xiàn),原本在PreRender才執(zhí)行的特定構(gòu)建步驟就要提前執(zhí)行,當(dāng)這樣的操作在不同階段進(jìn)行多幾次,構(gòu)建步驟就已經(jīng)散落在頁(yè)面生命周期的各階段。
  構(gòu)建步驟可能散落于頁(yè)面生命周期的各階段對(duì)于控件設(shè)計(jì)師來(lái)說(shuō)是一個(gè)嚴(yán)峻的問(wèn)題,這意味著他要保證任何一個(gè)構(gòu)建

下一頁(yè)
返回列表
返回首頁(yè) 主站蜘蛛池模板: 中文字幕精品无码亚洲字| 伊人久久大香线蕉综合影院首页| 在线天堂av影院| 少妇人妻在线视频| 久久伊人精品一区二区三区| 欧美性色19p| 人妻无码久久久久久久久久久| 色五五月五月开| 国产寡妇树林野战在线播放| **aaaaa毛片免费同男同女| 夭天曰天天躁天天摸在线观看 | 久久久无码人妻精品无码| 欧美另类69xxxxxhd| 亚洲色中文字幕在线播放| 精品无码成人片一区二区98 | 免费乱理伦在线播放| 老鸭窝laoyawo国产精品| 国产成 人 综合 亚洲专| 你懂的视频在线播放| 国农村精品国产自线拍| www.日韩av.com| 成全高清视频免费观看| 久久人人爽人人爽人人片av高请| 欧洲精品久久久AV无码电影| 亚洲欧美日韩一区在线观看| 琴帝type=小说| 再深点灬舒服了灬太大了乡村| 色人阁在线视频| 国产交换丝雨巅峰| 黄色软件下载免费观看| 国产精品一区12P| 456在线视频| 国语自产精品视频在线看| eeuss影院在线奇兵区1页| 强行扒开双腿猛烈进入| 中文字幕在线观看一区二区 | 亚洲成av人片在线观看无码不卡 | va天堂va亚洲va影视中文字幕| 成人午夜性a级毛片免费| 中文字幕永久视频| 日日摸日日碰夜夜爽亚洲|