青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

拂曉·明月·彎刀

觀望,等待只能讓出現的機會白白溜走

  C++博客 :: 首頁 ::  :: 聯系 :: 聚合  :: 管理 ::

注:本文轉自孟巖的博客(http://blog.csdn.net/myan)

假設你現在正在面試,主考不緊不慢地給出下一道題目:“請用C語言寫一個類似strcpy的函數。要考慮可能發生的異常情況。” 你會怎么做呢?很明顯,對方不是在考察你的編程能力,因為復制字符串實在太容易了。對方是在考察你的編程風格(習慣),或者說,要看看你編碼的質量。

下面是多種可能的做法:

void
string_copy1(char* dest, const char* source)
{
assert(dest != NULL); /* 使用斷言 */
assert(source != NULL);
while (*source != ‘\0′) {
*dest = *source;
++dest;
++source;
}

*dest = ‘\0′;
}

void
string_copy2(char* dest, const char* source)
{
if (dest != NULL && source != NULL) {  /* 對錯誤消極靜默 */
while (*source != ‘\0′) {
*dest = *source;
++dest;
++source;
}

*dest = ‘\0′;
}
}

int
string_copy3(char* dest, const char* source)
{
if (dest != NULL && source != NULL) {
while (*source != ‘\0′) {
*dest = *source;
++dest;
++source;
}

*dest = ‘\0′;
return SUCCESS;  /* 返回表示正確的值 */
}
else {
errno = E_INVALIDARG;  /* 設定錯誤號 */
return FAILED;         /*  返回表示錯誤的值 */
}
}
// C++
void
string_copy4(char* dest, const char* source)
{
if (dest == NULL || source == NULL)
throw Invalid_Argument_Error();  /*  拋出異常 */

while (*source != ‘\0′) {
*dest = *source;
++dest;
++source;
}

*dest = ‘\0′;
}

如果你是主考,不知道面對這樣四份答卷,你的評分如何?當然,你可以心里揣著一個“標準答案”,“順我者昌,逆我者亡”。但是如果以認真的態度面對這四份答卷,我想很多人都會難以抉擇。

因為這里涉及到了軟件開發中的一個帶有本質性的難題——錯誤處理。

歷來錯誤處理一直是軟件開發者所面臨的最大困難之一。Bjarne Stroustrup在談到其原因時說道,能夠探察錯誤的一方不知道如何處理錯誤,知道如何處理錯誤的一方沒有能力探察錯誤,而直接采用防御性代碼來解 決,會使得程序的正常結構被打亂,從而帶來更多的錯誤。這種困境是非常難以應對的——費心耗力而未必有回報。因此,更多的人采用鴕鳥戰術,對可能發生的錯 誤視而不見,任其自然。

C++、Java和其他語言對錯誤處理問題的回答是異常機制。這種機制在正常的程序執行流之外開辟了專門的信道,專門用來在不同程序模塊之間報告錯誤,解 決上述錯誤探察與處理策略分散的矛盾。然而,有了異常處理機制后,開發者開始有一種傾向,就是使用異常來處理所有的錯誤。我曾經就這個問題在 comp.lang.c++.moderated上展開討論,結果是發現有相當多的人,包括Boost開發組里的很多專家,都認為異常是錯誤處理的通用解 決方案。

對此我不能贊同。并且我認為濫用異常比不用異常的危害更大。

The Pragmatic Programmer是一本在國外程序員中間頗為流行的書,其中在講到錯誤處理時,有一句箴言:
“只在真正異常的狀況下使用異常。”

書中舉了一個例子,如果你需要當前目錄下的一個名叫“app.dat”的文件,而這個文件不存在,那么這不叫異常狀況,這是你應該預料到的、并且顯式處理 的情況。而如果你要到Windows目錄下尋找user.dat文件,卻沒找到,那才叫做異常狀況——因為每一個正常運行的Windows系統都應該有這 個文件。

我非常贊成書中的那句忠告,可是究竟什么是“真正異常”的狀況?書中的這個例子顯然只是一個頗具感性的、寓言似的故事,具有所有寓言的共同特點——讀起來覺得豁然開朗,收獲很大,實際上幫不了你什么忙。這種例子對于我們的實際開發,仍然提供不了真正的幫助。

究竟應該如何看待錯誤?怎樣才能最好地錯誤處理?

說實話,在這兩個問題上,我們所見到的大部分語言都沒有給出很好的回答。C秉承一貫風格,把所有的東西推給開發者考慮;Ada發明了異常,但是又為異常所 累(知道阿里亞納5火箭的處女航為什么失敗嗎?);C++企圖將Ada的異常機制融合進自己的體系中,結果異常成了C++中最難以處理的東西;Java和 C#顯然都沒有耐心重新考慮錯誤處理這樁事,而只是簡單的將C++的異常機制完善化了事。

與上述這些語言不同,Eiffel從一開始就把錯誤處理放在核心的位置上予以考慮,并以“契約”思想為核心,建立了整個的錯誤處理思想體系。在我了解的語 言里,Eiffel是對這個問題思考最為深刻一個,因此,Eiffel歷來享有“高質量系統開發語言”的聲譽。(事實上,Bertrand Meyer很不喜歡別人稱Eiffel為“編程語言”,他反復強調,Eiffel是一個Software Development Framework。不過本文只涉及語言特性,所以姑且稱Eiffel語言。)

Eiffel把軟件錯誤產生的本質歸結與“契約”的破壞。Eiffel認為,一個軟件能夠正常運作,正確完成任務,是需要一系列條件的。這些條件包括客觀 運行環境良好,操作者操作正確,軟件內部功能正確等等。因此,軟件的正確運行,是環境、操作者與軟件本身三方面合作的結果。相應的,系統的錯誤,也是由于 三者中有一方沒有正確履行自己的職責而導致的。細化到軟件內部,每個軟件都是由若干不同的模塊組成的,軟件的錯誤,是由于某些模塊沒有正確履行自己的職 責。要徹底杜絕軟件錯誤,只有分清各自模塊的責任,并且建立機制,敦促各模塊正確履行自己的責任,然后才有可能做到Bug-free。(鑒于系統中錯綜復 雜的關系,以及開發者認識能力的局限,我認為真正無錯誤的系統是不可能的。但是當前一般軟件系統中的質量問題遠遠比應有的嚴重。)

如何保證各方恪守職責呢?Eiffel引入了契約(Contract)這個概念。這里的契約與我們通常所說的商業契約很相似,有以下幾個特點:

1. 契約關系的雙方是平等的,對整個bussiness的順利進行負有共同責任,沒有哪一方可以只享有權利而不承擔義務。
2. 契約關系經常是相互的,權利和義務之間往往是互相捆綁在一起的;
3. 執行契約的義務在我,而核查契約的權力在人;
4. 我的義務保障的是你的利益,而你的義務保障的是我的利益;
將契約關系引入到軟件開發領域,尤其是面向對象領域之后,在觀念上給我們帶來了幾大沖擊:

1. 一般的觀點,在軟件體系中,程序庫和組件庫被類比為server,而使用程序庫、組件庫的程序被視為client。根據這種C/S關系,我們往往對庫程序 和組件的質量提出很嚴苛的要求,強迫它們承擔本不應該由它們來承擔的責任,而過分縱容client一方,甚至要求庫程序去處理明顯由于client錯誤造 成的困境。客觀上導致程序庫和組件庫的設計和編寫異常困難,而且質量隱患反而更多;同時client一方代碼大多松散隨意,質量低劣。這種情形,就好像在 一個權責不清的企業里,必然會養一批尸位素餐的混混,苦一批任勞任怨,不計得失的老黃牛。引入契約觀念之后,這種C/S關系被打破,大家都是平等的,你需 要我正確提供服務,那么你必須滿足我提出的條件,否則我沒有義務“排除萬難”地保證完成任務。

2. 一般認為在模塊中檢查錯誤狀況并且上報,是模塊本身的義務。而在契約體制下,對于契約的檢查并非義務,實際上是在履行權利。一個義務,一個權利,差別極大。例如上面的代碼:
if (dest == NULL) { … }
這就是義務,其要點在于,一旦條件不滿足,我方(義務方)必須負責以合適手法處理這尷尬局面,或者返回錯誤值,或者拋出異常。而:
assert(dest != NULL);
這是檢查契約,履行權利。如果條件不滿足,那么錯誤在對方而不在我,我可以立刻“撕毀合同”,罷工了事,無需做任何多余動作。這無疑可以大大簡化程序庫和組件庫的開發。

3. 契約所核查的,是“為保證正確性所必須滿足的條件”,因此,當契約被破壞時,只表明一件事:軟件系統中有bug。其意義是說,某些條件在到達我這里時,必 須已經確保為“真”。誰來確保?應該是系統中的其他模塊在先期確保。如果在我這里發現契約沒有被遵守,那么表明系統中其他模塊沒有正確履行自己的義務。就 拿上面提到的“打開文件”的例子來說,如果有一個模塊需要一個FILE*,而在契約檢查中發現該指針為NULL,則意味著有一個模塊沒有履行其義務,即 “檢查文件是否存在,確保文件以正確模式打開,并且保證指針的正確性”。因此,當契約檢查失敗時,我們首先要知道這意味著程序員錯誤,而且要做的不是糾正 契約核查方,而是糾正契約提供方。換句話說,當你發現:
assert(dest != NULL);
報錯時,你要做的不是去修改你的string_copy函數,而是要讓任何代碼在調用string_copy時確保dest指針不為空。

4. 我們以往對待“過程”或“函數”的理解是:完成某個計算任務的過程,這一看法只強調了其目標,沒有強調其條件。在這種理解下,我們對于exception 的理解非常模糊和寬泛:只要是無法完成這個計算過程,均可被視為異常,也不管是我自己的原因,還是其他人的原因(典型的權責不清)。正是因為這種模糊和寬 泛,“究竟什么時候應該拋出異常”成為沒有人能回答的問題。而引入契約之后,“過程”和“函數”被定義為:完成契約的過程。基于契約的相互性,如果這個契 約的失敗是因為其他模塊未能履行契約,本過程只需報告,無需以任何其他方式做出反應。而真正的異常狀況是“對方完全滿足了契約,而我依然未能如約完成任 務”的情形。這樣以來,我們就給“異常”下了一個清晰、可行的定義。

5. 一般來說,在面向對象技術中,我們認為“接口”是唯一重要的東西,接口定義了組件,接口確定了系統,接口是面向對象中我們唯一需要關心的東西,接口不僅是 必要的,而且是充分的。然而,契約觀念提醒我們,僅僅有接口還不充分,僅僅通過接口還不足以傳達足夠的信息,為了正確使用接口,必須考慮契約。只有考慮契 約,才可能實現面向對象的目標:可靠性、可擴展性和可復用性。反過來,“沒有契約的復用根本就是瞎胡鬧。(Bertrand Meyer語)”。

由上述觀點可以看出,雖然Eiffel所倡導的Design By Contract在表象上不過是系統化的斷言(assertion)機制,然而在背后,確實是完全的思想革新。正如Ivar Jacoboson訪華時對《程序員》雜志所說:“我認為Bertrand Meyer的方向——Design by Contract——是正確的方向,我們都會沿著他的足跡前進。我相信,大型廠商(微軟、IBM,當然還有Rational)都不會對Bertrand Meyer的成就坐視不理。所有這些廠商都會在這個方向上有所行動。”

posted on 2011-04-19 16:45 一路風塵 閱讀(406) 評論(0)  編輯 收藏 引用 所屬分類: 轉載
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲人成网站色ww在线| 日韩视频在线你懂得| 激情久久影院| 国产丝袜美腿一区二区三区| 久久综合给合| 国产麻豆综合| 国产精品久久久久久久一区探花 | 国产一区二区三区奇米久涩| 国产精品久久久免费| 国产精品女主播| 国产精品免费看久久久香蕉| 国产精品激情偷乱一区二区∴| 国产欧美1区2区3区| 国产精品久久一区二区三区| 国产精品免费在线| 亚洲电影视频在线| 一区二区三区不卡视频在线观看| 亚洲免费伊人电影在线观看av| 欧美一区二区三区在| 久久精品国产69国产精品亚洲| 欧美高清在线一区二区| 亚洲黑丝在线| 99国产精品久久| 亚洲欧美精品| 久久夜色精品一区| 猛男gaygay欧美视频| 欧美日韩精品高清| 国产女主播一区| 日韩视频中文字幕| 久久精品99无色码中文字幕| 欧美电影免费观看大全| 亚洲一区制服诱惑| 欧美激情成人在线视频| 国产亚洲欧美aaaa| 99国产精品国产精品久久 | 国产一区二区三区黄| 亚洲人成在线观看| 久久久综合精品| 国产精品99久久99久久久二8| 久久久久久久999精品视频| 国产精品麻豆va在线播放| 亚洲精品视频在线观看网站| 裸体素人女欧美日韩| 亚洲一区二区在线免费观看| 欧美激情小视频| 亚洲高清在线视频| 久久国产欧美日韩精品| 在线中文字幕日韩| 欧美天天视频| 夜夜嗨av一区二区三区免费区| 久久综合免费视频影院| 性久久久久久| 国产精品视频yy9299一区| 亚洲免费在线电影| 中文av一区特黄| 欧美日韩免费观看一区=区三区| 在线观看一区视频| 国产日本欧美一区二区三区在线| 欧美中在线观看| 欧美日韩一区在线观看视频| 亚洲国产高清一区| 免费av成人在线| 久久精品人人做人人爽电影蜜月 | 国产专区综合网| 久久精品国产亚洲一区二区三区 | 久久国产精品99国产精| 国产欧美精品xxxx另类| 欧美一区二区视频在线| 午夜精品久久久久99热蜜桃导演| 国产精品久久久久99| 午夜日韩福利| 久久狠狠一本精品综合网| 狠狠爱www人成狠狠爱综合网| 久久综合九色欧美综合狠狠| 免费永久网站黄欧美| 日韩视频中午一区| 亚洲少妇中出一区| 国产精品网站一区| 久久久人人人| 欧美韩日一区二区三区| 亚洲一级黄色片| 欧美一区二区三区精品电影| 精品福利电影| 日韩亚洲国产精品| 国产日韩亚洲| 欧美成人午夜77777| 欧美另类视频| 久久超碰97人人做人人爱| 久久美女艺术照精彩视频福利播放| 91久久黄色| 亚洲一区二区伦理| 在线看成人片| 亚洲免费影视| 亚洲麻豆视频| 欧美一区二区三区四区在线| 亚洲精品偷拍| 欧美一区二区三区久久精品茉莉花| 亚洲精品网址在线观看| 午夜在线视频一区二区区别| 亚洲精品乱码久久久久久按摩观 | 欧美日韩国产探花| 欧美中文在线免费| 欧美另类视频在线| 久久婷婷麻豆| 欧美日韩系列| 亚洲大胆美女视频| 欧美三级电影网| 欧美激情久久久| 国产精品一区二区三区久久| 免费日韩av片| 狠狠88综合久久久久综合网| 一本色道久久综合亚洲精品高清 | 小嫩嫩精品导航| 亚洲第一主播视频| 99精品国产热久久91蜜凸| 国产亚洲欧美另类中文| 欧美激情片在线观看| 一本色道久久综合亚洲精品小说| 日韩亚洲视频在线| 伊人久久综合97精品| 亚洲视频1区2区| 亚洲黄色毛片| 欧美精品国产精品| 午夜精品一区二区三区在线播放 | 亚洲欧美制服中文字幕| 女生裸体视频一区二区三区| 欧美在线综合| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ入口 | 欧美阿v一级看视频| 久久久久久999| 国产精品美女久久福利网站| 亚洲国产精品一区制服丝袜| 国外精品视频| 亚洲国产精品一区在线观看不卡 | 国产精品成人一区二区网站软件| 欧美激情第3页| 伊人一区二区三区久久精品| 欧美亚洲一区在线| 久久不射2019中文字幕| 亚洲午夜国产成人av电影男同| 在线观看一区视频| 亚洲视频欧美视频| 亚洲精品国产精品国产自| 久久久久国内| 毛片一区二区三区| 黄色av一区| 久久九九久精品国产免费直播| 性色av一区二区三区在线观看| 欧美日韩理论| 一区二区三区四区国产精品| 亚洲欧洲av一区二区| 国产精品嫩草影院av蜜臀| 在线视频日本亚洲性| 亚洲欧美精品| 国产精品永久免费观看| 亚洲欧美日韩天堂一区二区| 欧美一区三区三区高中清蜜桃| 欧美视频一区在线| 亚洲天堂免费观看| 久久aⅴ国产紧身牛仔裤| 国产亚洲精品久久久| 久久精品国产综合| 欧美高清hd18日本| 夜色激情一区二区| 亚洲福利久久| 欧美精品一区在线观看| 欧美高清在线精品一区| 亚洲黄色尤物视频| 欧美伦理a级免费电影| 亚洲欧美在线一区二区| 可以看av的网站久久看| 99精品视频免费观看视频| 欧美午夜一区二区三区免费大片 | 亚洲欧美日韩高清| 欧美成ee人免费视频| 在线午夜精品| 激情综合视频| 欧美午夜在线| 亚洲欧洲精品一区二区精品久久久| 欧美理论在线| 欧美在线视频观看免费网站| 欧美黑人多人双交| 午夜亚洲福利| 亚洲伦伦在线| 国产一区二区毛片| 欧美性一区二区| 久久亚洲一区二区三区四区| 亚洲一区二区三| 亚洲国产91色在线| 久久www成人_看片免费不卡| 亚洲欧洲精品一区二区三区不卡 | 国产日韩精品一区| 亚洲福利视频二区| 欧美日韩123| 欧美在线综合视频| 99国产麻豆精品| 亚洲福利精品| 久久夜色精品国产欧美乱| 亚洲在线播放| 99在线热播精品免费99热|