日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
契約式編程與防御式編程

背景

10年積累的成都做網(wǎng)站、網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有黃島免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

事情的來(lái)由還要從幾十幾億年前的一次星球大爆炸說(shuō)起,sorry,背錯(cuò)臺(tái)詞了,是從幾天前討論接口返回?cái)?shù)據(jù)和幾個(gè)月前討論課件本地?cái)?shù)據(jù)結(jié)構(gòu)說(shuō)起,簡(jiǎn)單的說(shuō),就是碰到約定好的內(nèi)容出現(xiàn)異常,是我們?cè)诔绦蛑袃?nèi)部作兼容處理,還是拋出去。

打個(gè)比方,我們要解析一段json,約定這個(gè)json的格式,只能是正常格式,或者是空,那么一旦返回json的方法返回了一個(gè)『既不是正常格式,又不是空的異常值』,程序該如何處理呢?

小花:一旦碰到約定異常,程序必須兼容處理,一定不能讓程序Crash小Fa:一旦碰到約定異常,就必須拋出去,告知約定有誤,找出具體錯(cuò)誤原因

這個(gè)問(wèn)題,相信只要是程序猿基本都遇到過(guò),舉個(gè)最常見(jiàn)的栗子,NullPointerException,假如我們要從json中取一個(gè)字段,突然發(fā)現(xiàn)發(fā)生了NullPointerException,一些開(kāi)發(fā)者認(rèn)為是數(shù)據(jù)問(wèn)題,那么把json中的這個(gè)字段改正確就行了;還有一些開(kāi)發(fā)者認(rèn)為是程序問(wèn)題,認(rèn)為程序需要做非空判斷,再去使用。我相信這兩種程序猿都有自己的理由,***種程序簡(jiǎn)潔明了,代碼邏輯干凈,但一旦出錯(cuò),就會(huì)崩潰,第二種程序耐操,隨你數(shù)據(jù)怎么錯(cuò),我都能不Crash,但代碼中到處存在非空判斷,臃腫、重復(fù)。

生存還是毀滅,這是一個(gè)問(wèn)題!

防御式編程

就在我們?yōu)榱诉@個(gè)問(wèn)題而爭(zhēng)論的時(shí)候,突然有一個(gè)姓康的同事,施法祭出了一塊磚頭(《代碼大全2》,近900頁(yè),相當(dāng)于3本《Android群英傳》),我一度以為他想砸在我的臉上,正當(dāng)我準(zhǔn)備閃避的時(shí)候,他翻到了這塊磚頭的第八章,幾個(gè)大字赫然印入了我的視線——『防御式編程』。

果然是老司機(jī),居然可以從防御性駕駛中悟出防御性編程,說(shuō)好的編程不開(kāi)車,開(kāi)車不編程呢?

這位作者編程厲不厲害我不知道,但我知道,論開(kāi)車,一定沒(méi)有何老師diao!

OK,《代碼大全》給我們提供了一個(gè)定義——『防御式編程』,說(shuō)白了,就是『人類都是不安全、不值得信任的,所有的人,都會(huì)犯錯(cuò)誤,而你寫(xiě)的代碼,應(yīng)該考慮到所有可能發(fā)生的錯(cuò)誤,讓你的程序不會(huì)因?yàn)樗说腻e(cuò)誤而發(fā)生錯(cuò)誤』

在書(shū)中,作者告訴我們,程序需要對(duì)可能的錯(cuò)誤輸入,做出兼容,例如一個(gè)除法的函數(shù),你必須判斷分母可能為0的情況,從而給調(diào)用者返回錯(cuò)誤提示。另外,一般的高級(jí)編程語(yǔ)言,都提供了『斷言』和『異常』兩種方式來(lái)進(jìn)行錯(cuò)誤處理。

斷言

斷言,是一種在開(kāi)發(fā)階段使用的,讓程序在運(yùn)行時(shí)進(jìn)行自檢的代碼,斷言為真,那么程序運(yùn)行正常,斷言為假,那么程序運(yùn)行異常退出。等等,防御式編程不是說(shuō)好的要兼容異常嗎,為什么會(huì)退出?實(shí)際上,作者的意思是,先斷言、后處理錯(cuò)誤,而斷言是在開(kāi)發(fā)環(huán)境中的,正式上線后是不會(huì)有斷言的。

但實(shí)際上,這是一個(gè)悖論,開(kāi)發(fā)階段的錯(cuò)誤處理代碼在開(kāi)發(fā)階段被斷言給攔截掉了,但錯(cuò)誤處理代碼也是人寫(xiě)的,那么如何去檢測(cè)『錯(cuò)誤處理代碼可能發(fā)生的錯(cuò)誤』呢?

異常

當(dāng)代碼出現(xiàn)問(wèn)題時(shí),可以通過(guò)拋出異常來(lái)進(jìn)行通知,如果你無(wú)法處理,則可以交給外界進(jìn)行處理。這個(gè)不多說(shuō),畢竟大部分代碼,如果有異常,最簡(jiǎn)單的就是try catch了,我甚至見(jiàn)過(guò)把所以代碼直接try catch的,你是有多不相信人類。

所以我覺(jué)得防御式編程用久了,會(huì)不會(huì)開(kāi)始懷疑人生,果然,在往后翻幾頁(yè),作者也給出了建議。

借用奇異博士的一句臺(tái)詞——『你TM居然把警告寫(xiě)在咒語(yǔ)的下一頁(yè)』!

簡(jiǎn)而言之,防御式編程,就是持懷疑態(tài)度審視所有的代碼,但這個(gè)和我們討論的主題還是略有不同的,我們討論的主題是『已經(jīng)有了約定,但返回了約定之外的內(nèi)容』。

契約式編程

就在我們討論的時(shí)候,天空突然飄來(lái)五個(gè)字——那都不是事,哦不對(duì),是『契約式編程』。

這個(gè)好像有點(diǎn)像!我們先來(lái)簡(jiǎn)單的看下什么是契約式編程,簡(jiǎn)單的說(shuō),契約作用于兩方,每一方都會(huì)完成一些任務(wù),從而促成契約的達(dá)成,但同時(shí),每一方也會(huì)接受一些義務(wù),作為制定契約的前提,有任意一方無(wú)視了必盡義的義務(wù),則契約失敗。

契約式編程要求我們?cè)凇呵疤釛l件』、『后繼條件』和『不變量條件』進(jìn)行契約的檢查。類似的,例如檢查參數(shù),一旦參數(shù)不對(duì),當(dāng)即撕毀契約。這一點(diǎn),現(xiàn)在很多新的語(yǔ)言都支持了,例如Swift,就支持對(duì)參數(shù)進(jìn)行約束檢查,這就是一種類契約式編程。

契約所約束的,是『一個(gè)為了確保程序正常運(yùn)行的條件』,一旦契約被損毀,只有一個(gè)原因,那就是程序出了Bug,例如一個(gè)數(shù)據(jù)字段,在我處理的時(shí)候,必須保證是不為空的,那么誰(shuí)來(lái)保證這一點(diǎn)呢,一定是我的調(diào)用方(或者說(shuō)是其它模塊),所以,一旦出現(xiàn)問(wèn)題,應(yīng)該有調(diào)用方來(lái)檢查,確保調(diào)用的時(shí)候,必須是不為空的。

這讓我想到了剛開(kāi)始在面向日本人編程時(shí)期的一些事,日本人的做事風(fēng)格是出了名的謹(jǐn)慎和詳細(xì),每一個(gè)方法、函數(shù),在詳細(xì)設(shè)計(jì)的時(shí)候,就已經(jīng)把參數(shù)、返回值,已經(jīng)它們的類型和所有可能的值都設(shè)計(jì)好了,每個(gè)方法之間有著明確的界限,如果你的方法因?yàn)閭魅氲膮?shù)不在設(shè)計(jì)范圍內(nèi)而導(dǎo)致錯(cuò)誤,你完全可以去找調(diào)用方,要求他按照設(shè)計(jì)來(lái)進(jìn)行調(diào)用。不得不說(shuō),這應(yīng)該是契約編程的***實(shí)踐。日企普遍使用這種方式其實(shí)還有一個(gè)原因,那就是可以嚴(yán)格區(qū)分責(zé)任,讓每個(gè)人都不必為了遷就他人的錯(cuò)誤而進(jìn)行『艱難的編碼』。每個(gè)人按照契約處理好自己的事情,讓損毀契約的人承擔(dān)責(zé)任。

再引申一下,這和現(xiàn)在的『面向接口編程』也非常類似,兩個(gè)模塊之間,定義好調(diào)用、處理的接口,而具體的實(shí)現(xiàn),對(duì)方都不用關(guān)心,只要安裝協(xié)議的接口來(lái)進(jìn)行開(kāi)發(fā)就可以了,但光有接口也不夠,還需要契約來(lái)做進(jìn)一步的約束,例如參數(shù)、返回值的約束。

無(wú)獨(dú)有偶,在《代碼大全》中,作者也提出了『進(jìn)攻式編程』,其實(shí)和契約編程,有異曲同工之妙。

烏托邦

OK,夢(mèng)醒了,讓陽(yáng)光照進(jìn)現(xiàn)實(shí)。以上兩種編程方式,都是非常理想化的編程,但在一般的公司里面不論是防御還是契約,實(shí)現(xiàn)起來(lái)都是比較困難的,例如前端與后端的接口、不同部門(mén)同事的交流,按照契約式編程,沒(méi)人Care你的契約,按照防御式編程,代碼慘不忍睹,還容易漏掉防御。那么到底該怎么辦呢,我認(rèn)為,如果能在公司層面推廣契約式編程,首先是對(duì)開(kāi)發(fā)效率的提升,讓每個(gè)人都對(duì)自己寫(xiě)的代碼負(fù)責(zé),在開(kāi)發(fā)者之間建立良好的信任關(guān)系,同時(shí)也能減少不必要的溝通成本和精力。但同時(shí),必要的防御式編程也是不能少的,這是保證程序健壯、穩(wěn)定的前提。怎么說(shuō)呢,中國(guó)人民秉承了千百年的傳統(tǒng)——『中庸之道』,契約還是防御,視情況而定,這是平衡的藝術(shù)。

警告

本文請(qǐng)使用防御式閱讀,每個(gè)人都會(huì)犯錯(cuò),歡迎留言交流。

此文一出,很有可能引發(fā)雙方混戰(zhàn),紅與黑,天災(zāi)還是近衛(wèi),聯(lián)盟還是部落,Choose your side。


網(wǎng)站欄目:契約式編程與防御式編程
網(wǎng)站路徑:http://www.dlmjj.cn/article/coejdop.html