337p人体粉嫩胞高清图片,97人妻精品一区二区三区在线 ,日本少妇自慰免费完整版,99精品国产福久久久久久,久久精品国产亚洲av热一区,国产aaaaaa一级毛片,国产99久久九九精品无码,久久精品国产亚洲AV成人公司
網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

TypeScript程序員栽了:47%生產(chǎn)事故源自這種"合法"代

0
分享至


去年某跨境電商平臺(tái)大促,凌晨3點(diǎn)支付系統(tǒng)崩潰。排查日志發(fā)現(xiàn):一筆訂單狀態(tài)顯示"已支付",卻找不到對(duì)應(yīng)發(fā)票ID。代碼完全合規(guī),TypeScript編譯通過(guò),測(cè)試覆蓋率87%——但業(yè)務(wù)規(guī)則被悄無(wú)聲息地撕碎了。

這不是孤例。作者統(tǒng)計(jì)過(guò)自己經(jīng)手的生產(chǎn)事故,近半數(shù)bug并非算法錯(cuò)誤或基礎(chǔ)設(shè)施故障,而是"無(wú)效狀態(tài)"在作祟:空訂單、超額支付、已發(fā)貨卻無(wú)物流單號(hào)。類(lèi)型系統(tǒng)對(duì)此視而不見(jiàn),它只檢查語(yǔ)法,不守護(hù)業(yè)務(wù)邏輯。

本文拆解一套讓"非法狀態(tài)"在編譯期就暴露的建模模式。核心思路很樸素:把業(yè)務(wù)規(guī)則寫(xiě)進(jìn)類(lèi)型本身,而非注釋或某個(gè)校驗(yàn)函數(shù)。當(dāng)違規(guī)操作發(fā)生時(shí),代碼要么編譯失敗,要么顯式報(bào)錯(cuò)——沒(méi)有第三種可能。

「合法」的陷阱:一個(gè)典型Order類(lèi)的隱患

先看這段被無(wú)數(shù)項(xiàng)目復(fù)制的代碼:

class Order { status: "DRAFT" | "PLACED" | "PAID"; items: OrderItem[]; invoiceId?: string; }

問(wèn)題藏在問(wèn)號(hào)里。invoiceId是可選的,但業(yè)務(wù)規(guī)則要求:PAID狀態(tài)的訂單必須有發(fā)票ID。TypeScript不會(huì)阻止你創(chuàng)建一個(gè){status: "PAID", invoiceId: undefined}的對(duì)象,運(yùn)行時(shí)也不會(huì)自動(dòng)攔截。

常見(jiàn)的補(bǔ)救方案是在"支付完成"的用例里加校驗(yàn)。但作者指出致命漏洞:校驗(yàn)只發(fā)生在特定路徑,狀態(tài)本身仍可被任意篡改。另一個(gè)開(kāi)發(fā)者、一段遺留腳本、甚至未來(lái)的你自己,都可能繞過(guò)這層防護(hù)直接修改對(duì)象。

更隱蔽的風(fēng)險(xiǎn)是"讀操作污染"。假設(shè)某報(bào)表功能直接讀取Order狀態(tài)生成對(duì)賬單,它不會(huì)觸發(fā)支付用例的校驗(yàn)——臟數(shù)據(jù)就這樣流入了財(cái)務(wù)系統(tǒng)。

不變量:把規(guī)則焊進(jìn)類(lèi)型系統(tǒng)

作者提出的解法是"不變量"(Invariant)模式。不變量是一條必須恒成立的業(yè)務(wù)規(guī)則,而非某個(gè)時(shí)點(diǎn)的校驗(yàn)條件。

實(shí)現(xiàn)上,基類(lèi)DomainEntity在構(gòu)造函數(shù)中注冊(cè)規(guī)則,每次readState()時(shí)自動(dòng)執(zhí)行:

const paidOrderHasInvoiceId = new BaseDomainInvariant( "Paid Order Has Invoice Id", (state) => { if (state.status === "PAID") { return state.invoiceId !== undefined; } return true; } );


Order實(shí)體在實(shí)例化時(shí)聲明這些約束:

class Order extends DomainEntity { private constructor(id: string, state: OrderState) { super(id, state); this.addInvariant(orderHasAtLeastOneItem); this.addInvariant(paidOrderHasInvoiceId); } }

關(guān)鍵設(shè)計(jì)在于readState()的強(qiáng)制性。作者刻意封禁了直接屬性訪(fǎng)問(wèn),所有狀態(tài)讀取必須經(jīng)過(guò)這個(gè)方法。一旦不變量被違反,立即拋出"Corrupted state detected"——錯(cuò)誤無(wú)法被靜默吞沒(méi),也無(wú)法被下游代碼忽略。

這套機(jī)制解決了前文提到的"讀操作污染"。報(bào)表功能調(diào)用order.readState()時(shí),不變量同樣生效。臟數(shù)據(jù)在源頭就被攔截,不會(huì)擴(kuò)散。

不變量還支持組合運(yùn)算,應(yīng)對(duì)復(fù)雜業(yè)務(wù)場(chǎng)景:

const complexRule = invariantA.and(invariantB).or(invariantC);

Result模式:讓失敗成為顯式契約

TypeScript的throw有一個(gè)設(shè)計(jì)缺陷:異常類(lèi)型不出現(xiàn)在函數(shù)簽名中。調(diào)用方除非閱讀實(shí)現(xiàn)代碼,否則無(wú)法預(yù)知哪些錯(cuò)誤可能發(fā)生。這在大型代碼庫(kù)中制造了持續(xù)的"驚喜"。

作者引入Result模式,將失敗作為一等公民納入類(lèi)型系統(tǒng):

lockCredits(params: { amount: number }): Result { if (this.state.subCreditBalance < params.amount) { return err(new NotEnoughFunds( `Not enough credits`, { available: this.state.subCreditBalance, amount: params.amount } )); } // ... }

返回類(lèi)型明確宣告:此操作可能成功(CreditLocked),也可能因余額不足失敗(NotEnoughFunds)。調(diào)用方必須處理兩種情形,編譯器會(huì)強(qiáng)制檢查分支完整性。

對(duì)比傳統(tǒng)try-catch,Result模式的優(yōu)勢(shì)在于錯(cuò)誤處理的局部性與可組合性。異常在調(diào)用棧中跳躍,常常在最不合適的層級(jí)被捕獲;Result則要求每層顯式傳遞或轉(zhuǎn)換錯(cuò)誤,形成清晰的錯(cuò)誤處理鏈條。

作者團(tuán)隊(duì)在實(shí)踐中發(fā)現(xiàn),Result模式顯著降低了"意外崩潰"的頻率。當(dāng)所有失敗路徑都被類(lèi)型強(qiáng)制暴露,遺漏處理的情形在編譯期就能被靜態(tài)分析捕獲。


從"防御式編程"到"不可能狀態(tài)"

這些模式的共同目標(biāo),是讓無(wú)效狀態(tài)在代碼層面"無(wú)法被構(gòu)造"。作者引用了一條設(shè)計(jì)原則:"Make illegal states unrepresentable"——與其到處校驗(yàn),不如讓非法組合根本寫(xiě)不出來(lái)。

以訂單狀態(tài)機(jī)為例。傳統(tǒng)實(shí)現(xiàn)用字符串枚舉加校驗(yàn)函數(shù),作者建議改用狀態(tài)作為類(lèi)型

DraftOrder、PlacedOrder、PaidOrder成為獨(dú)立的類(lèi),各自持有該狀態(tài)允許的字段。PaidOrder的構(gòu)造函數(shù)強(qiáng)制要求invoiceId,不存在"可選"的漏洞。狀態(tài)轉(zhuǎn)換通過(guò)顯式方法實(shí)現(xiàn):draft.place()返回PlacedOrder,placed.pay(invoiceId)返回PaidOrder。

這種設(shè)計(jì)下,你無(wú)法在編譯通過(guò)的代碼中構(gòu)造出"已支付但無(wú)發(fā)票"的訂單。業(yè)務(wù)規(guī)則從"運(yùn)行時(shí)校驗(yàn)"降級(jí)為"類(lèi)型系統(tǒng)約束",從"可能遺漏"升級(jí)為"物理上不可能"。

代價(jià)是代碼量增加。每個(gè)狀態(tài)一個(gè)類(lèi),轉(zhuǎn)換方法需要維護(hù)。但作者認(rèn)為,這與生產(chǎn)事故的排查成本相比微不足道——尤其是當(dāng)bug發(fā)生在凌晨、涉及資金、需要跨時(shí)區(qū)協(xié)調(diào)時(shí)。

某次內(nèi)部復(fù)盤(pán)顯示,采用這套模式后,團(tuán)隊(duì)狀態(tài)相關(guān)bug下降62%,平均修復(fù)時(shí)間從4.2小時(shí)降至23分鐘。因?yàn)殄e(cuò)誤總是在第一時(shí)間、最接近源頭處被捕獲,而非在下游系統(tǒng)的某個(gè)角落爆炸。

何時(shí)不必過(guò)度設(shè)計(jì)

作者也劃定了適用范圍。不變量與Result模式適合核心業(yè)務(wù)實(shí)體與資金相關(guān)操作,而非所有CRUD場(chǎng)景。一個(gè)內(nèi)部管理后臺(tái)的配置表單,用傳統(tǒng)校驗(yàn)足矣。

判斷標(biāo)準(zhǔn)是狀態(tài)錯(cuò)誤的代價(jià):如果臟數(shù)據(jù)可能流入財(cái)務(wù)系統(tǒng)、觸發(fā)合規(guī)審計(jì)、或?qū)е掠脩?hù)資金損失,則值得投入。如果最壞結(jié)果只是顯示異常,可重新提交,則保持簡(jiǎn)單。

另一個(gè)考量是團(tuán)隊(duì)規(guī)模。小型團(tuán)隊(duì)、快速迭代階段,嚴(yán)格類(lèi)型約束可能成為拖累。但當(dāng)代碼庫(kù)超過(guò)10萬(wàn)行、貢獻(xiàn)者超過(guò)15人,"防御式編程"的隱性成本會(huì)指數(shù)級(jí)上升——你永遠(yuǎn)不知道誰(shuí)的PR繞過(guò)了哪層校驗(yàn)。

作者最后提到一個(gè)反直覺(jué)的觀察:最危險(xiǎn)的代碼往往是"看起來(lái)沒(méi)問(wèn)題"的。那些顯式拋出異常、返回錯(cuò)誤碼的函數(shù),調(diào)用者自然保持警惕;而那些默默返回、類(lèi)型正確的函數(shù),反而成為bug的溫床。這套模式的核心,正是把這種隱性風(fēng)險(xiǎn)轉(zhuǎn)化為顯式契約。

你的代碼庫(kù)里,有多少"合法"的無(wú)效狀態(tài)正在沉睡?下次Code Review時(shí),不妨檢查那些可選字段與字符串枚舉——它們可能是凌晨告警的伏筆。

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶(hù)上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點(diǎn)推薦
伊朗武裝部隊(duì)向以色列發(fā)射新一輪導(dǎo)彈

伊朗武裝部隊(duì)向以色列發(fā)射新一輪導(dǎo)彈

財(cái)聯(lián)社
2026-03-26 19:42:42
4000萬(wàn)求購(gòu)羅馬指揮官,國(guó)米為齊沃新思路“拼了”

4000萬(wàn)求購(gòu)羅馬指揮官,國(guó)米為齊沃新思路“拼了”

里芃芃體育
2026-03-26 11:15:07
在哪一瞬間,對(duì)你老公徹底失望了?網(wǎng)友:強(qiáng)行分居兩年,然后離婚

在哪一瞬間,對(duì)你老公徹底失望了?網(wǎng)友:強(qiáng)行分居兩年,然后離婚

另子維愛(ài)讀史
2026-03-24 21:15:00
4月1日起,微信支付寶轉(zhuǎn)賬規(guī)則大變!這3個(gè)習(xí)慣趕緊改

4月1日起,微信支付寶轉(zhuǎn)賬規(guī)則大變!這3個(gè)習(xí)慣趕緊改

老特有話(huà)說(shuō)
2026-03-25 15:30:13
掀掉洋蔥頂,整治宗教泛濫的第一步

掀掉洋蔥頂,整治宗教泛濫的第一步

黑哥講現(xiàn)代史
2026-03-14 15:46:38
我發(fā)現(xiàn)一個(gè)真相:資本愛(ài)找孫穎莎代言,根本不只是因?yàn)樗辛髁浚?>
    </a>
        <h3>
      <a href=小光侃娛樂(lè)
2026-03-25 13:40:05
凈利潤(rùn)暴跌90%!理想的銷(xiāo)量神話(huà)破滅

凈利潤(rùn)暴跌90%!理想的銷(xiāo)量神話(huà)破滅

大佬灼見(jiàn)
2026-03-13 12:23:26
扎心!俄愛(ài)國(guó)軍事博主攤牌:再征40萬(wàn)大軍也白搭,戰(zhàn)場(chǎng)早已變天!

扎心!俄愛(ài)國(guó)軍事博主攤牌:再征40萬(wàn)大軍也白搭,戰(zhàn)場(chǎng)早已變天!

老馬拉車(chē)莫少裝
2026-03-25 07:41:30
王楚欽師娘爆料!孫穎莎無(wú)論是長(zhǎng)相性格還是人品,都是無(wú)以倫比的

王楚欽師娘爆料!孫穎莎無(wú)論是長(zhǎng)相性格還是人品,都是無(wú)以倫比的

大中國(guó)
2026-03-24 15:25:36
卡塔爾正式宣布暫停跟中國(guó)的合同,而且短時(shí)間內(nèi)不會(huì)恢復(fù)

卡塔爾正式宣布暫停跟中國(guó)的合同,而且短時(shí)間內(nèi)不會(huì)恢復(fù)

南權(quán)先生
2026-03-25 15:19:55
49歲翁帆突傳“喜訊”!喪夫5個(gè)月后高調(diào)露面,狀態(tài)好到出人意料

49歲翁帆突傳“喜訊”!喪夫5個(gè)月后高調(diào)露面,狀態(tài)好到出人意料

查爾菲的筆記
2026-03-16 19:12:07
中共中央批準(zhǔn),開(kāi)除劉慧黨籍

中共中央批準(zhǔn),開(kāi)除劉慧黨籍

新京報(bào)政事兒
2026-03-26 17:13:05
人類(lèi)史上最高級(jí)零元購(gòu),榨干印度200年,留下45萬(wàn)億天價(jià)賬單

人類(lèi)史上最高級(jí)零元購(gòu),榨干印度200年,留下45萬(wàn)億天價(jià)賬單

掠影后有感
2026-03-26 10:39:36
哈薩克斯坦也沒(méi)想到,跟著中國(guó)混來(lái)混去,結(jié)果自己也混成了個(gè)霸主

哈薩克斯坦也沒(méi)想到,跟著中國(guó)混來(lái)混去,結(jié)果自己也混成了個(gè)霸主

說(shuō)歷史的老牢
2026-03-26 01:18:38
小米捷報(bào),誤傷寧德時(shí)代

小米捷報(bào),誤傷寧德時(shí)代

ZAKER新聞
2026-03-26 22:10:32
2-0晉級(jí)八強(qiáng)!中國(guó)女網(wǎng)15歲新星連續(xù)爆冷真猛:下一輪對(duì)決王曦雨

2-0晉級(jí)八強(qiáng)!中國(guó)女網(wǎng)15歲新星連續(xù)爆冷真猛:下一輪對(duì)決王曦雨

李喜林籃球絕殺
2026-03-26 17:04:26
美軍發(fā)布戰(zhàn)果,摧毀中國(guó)產(chǎn)戰(zhàn)機(jī),伊朗空軍損失殆盡

美軍發(fā)布戰(zhàn)果,摧毀中國(guó)產(chǎn)戰(zhàn)機(jī),伊朗空軍損失殆盡

愛(ài)吃醋的貓咪
2026-03-22 22:29:08
看了“秦嵐”的穿搭,我悟了:灰色不配亮色、白色,才更時(shí)髦減齡

看了“秦嵐”的穿搭,我悟了:灰色不配亮色、白色,才更時(shí)髦減齡

蓓小西
2026-03-23 08:31:26
倒計(jì)時(shí)36天預(yù)警!黃金或迎拋售潮,多國(guó)限金條出口,中國(guó)已搶先布局

倒計(jì)時(shí)36天預(yù)警!黃金或迎拋售潮,多國(guó)限金條出口,中國(guó)已搶先布局

哄動(dòng)一時(shí)啊
2026-03-26 20:23:42
富人的生活能有多夸張?網(wǎng)友:根本找不到心動(dòng)還門(mén)當(dāng)戶(hù)對(duì)的人

富人的生活能有多夸張?網(wǎng)友:根本找不到心動(dòng)還門(mén)當(dāng)戶(hù)對(duì)的人

帶你感受人間冷暖
2026-03-27 00:05:14
2026-03-27 01:35:00
爬蟲(chóng)飼養(yǎng)員
爬蟲(chóng)飼養(yǎng)員
業(yè)余養(yǎng)了只叫“龍蝦”的AI爬蟲(chóng),主業(yè)是給互聯(lián)網(wǎng)打工。
170文章數(shù) 1關(guān)注度
往期回顧 全部

科技要聞

美團(tuán)發(fā)布外賣(mài)大戰(zhàn)后成績(jī)單:虧損超200億

頭條要聞

張雪峰留巨額遺產(chǎn):二婚妻子或拿50% 剩下的女兒占1/3

頭條要聞

張雪峰留巨額遺產(chǎn):二婚妻子或拿50% 剩下的女兒占1/3

體育要聞

申京努力了,然而杜蘭特啊

娛樂(lè)要聞

劉曉慶妹妹發(fā)聲!稱(chēng)姐姐受身邊人挑撥

財(cái)經(jīng)要聞

油價(jià)"馴服"特朗普?一到100美元就TACO

汽車(chē)要聞

一汽奧迪A6L e-tron開(kāi)啟預(yù)售 CLTC最大續(xù)航815km

態(tài)度原創(chuàng)

藝術(shù)
時(shí)尚
本地
家居
軍事航空

藝術(shù)要聞

都說(shuō)烏克蘭美女多,看完攝影師貝格瑪 的作品我信了!

400萬(wàn)人愛(ài)過(guò)的女孩,被黃謠網(wǎng)暴180天后

本地新聞

救命,這只醬板鴨已經(jīng)在我手機(jī)復(fù)仇了一萬(wàn)遍

家居要聞

傍海而居 靜觀蝴蝶海

軍事要聞

擔(dān)心特朗普突然停戰(zhàn) 以總理下令48小時(shí)盡力摧毀伊設(shè)施

無(wú)障礙瀏覽 進(jìn)入關(guān)懷版