漏洞少、成本低……極簡(jiǎn)代碼的終極優(yōu)勢(shì)(極簡(jiǎn)源碼)
全文共2927字,預(yù)計(jì)學(xué)習(xí)時(shí)長(zhǎng)6分鐘
圖片來(lái)源:Unsplash/ K8
知名作家Jules Verne道出了一句真理:極簡(jiǎn)適用于所有事物。
當(dāng)今世界,極簡(jiǎn)被廣泛應(yīng)用于各種事物,代碼也不例外。然而令人沮喪的事實(shí)是:當(dāng)前的代碼過(guò)于冗長(zhǎng)。更準(zhǔn)確地說(shuō),不必要的代碼太多,已經(jīng)到了妨礙有效代碼的地步。
也就是說(shuō),不必要的代碼本質(zhì)就是有害的:它會(huì)腐爛,需要定期維護(hù),需要找出漏洞。新特征意味著要更新舊代碼。代碼越多,存在漏洞的地方就越多。校驗(yàn)或編譯所需的時(shí)間越長(zhǎng),新員工理解編譯系統(tǒng)所需的時(shí)間也越長(zhǎng)。
除此之外,代碼是由工程師編寫(xiě)的。要寫(xiě)的代碼越多,需要的工程師就越多,進(jìn)而溝通成本也越高,并進(jìn)一步促進(jìn)代碼維護(hù)和開(kāi)發(fā)成本的不斷提高。
解決上述所有問(wèn)題的一個(gè)方法就是減少代碼量。
減少代碼量有很多好處:
· 開(kāi)發(fā)的代碼越少=開(kāi)發(fā)成本越低
· 開(kāi)發(fā)的代碼越少=維護(hù)成本越低
· 開(kāi)發(fā)的代碼越少=代碼漏洞越少
· 開(kāi)發(fā)的代碼越少=有效檢測(cè)越多
最最重要的一點(diǎn)是:代碼量越少,人們閱讀代碼的概率越高。
以下介紹一些減少代碼量的方法。
你不需要它
你不需要它(You Aren’t Gonna Need It,通??s寫(xiě)為YAGNI)是一個(gè)極限編程原則,指:
“等你真正要用的時(shí)候再編碼,永遠(yuǎn)不要因?yàn)槟悴聹y(cè)以后將會(huì)用到而編碼?!?/p>
即使你百分百確定之后將會(huì)用到某一個(gè)特征,也不要現(xiàn)在就編寫(xiě)代碼。
實(shí)行YAGNI原則主要基于兩個(gè)原因:
· 第一,避免寫(xiě)不必要的代碼可以節(jié)省時(shí)間。
· 第二,猜測(cè)或多或少會(huì)出錯(cuò),而因猜測(cè)提前寫(xiě)下的代碼則會(huì)一直在,并損害代碼的整體表現(xiàn)。避免寫(xiě)不必要的代碼可以使最終完成的代碼性能更好。
YAGNI原則對(duì)所有項(xiàng)目管理都是合理有效的。好的代碼設(shè)計(jì)考慮周到,特征平衡。不好的代碼設(shè)計(jì)則塞滿了各種糟糕設(shè)計(jì),變得運(yùn)轉(zhuǎn)不靈,成為“維護(hù)的噩夢(mèng)”。
這帶給我們的經(jīng)驗(yàn)法則就是,專注于明確需要的事物,不要被可能需要的事物分心。
圖片來(lái)源:Unsplash/Kobu Agency
不要寫(xiě)防彈代碼
防彈代碼指在任何輸入或意外條件下都能起效的完美代碼。
這是一種非常吸引人的想法,特別是對(duì)于那些不能容忍代碼在某些場(chǎng)景下失效的高級(jí)開(kāi)發(fā)人員。即便如此,編寫(xiě)或嘗試編寫(xiě)防彈代碼不僅不切實(shí)際,而且不必要,因?yàn)槭澜缟系乃惺挛?,包括軟件,都有其局限性?/p>
要試著編寫(xiě)一個(gè)完美的模塊,就要編寫(xiě)額外的條件,而這將會(huì)使代碼變得非常復(fù)雜,毀掉編寫(xiě)代碼的初衷。到時(shí)候,模塊會(huì)變得更龐大、成本更高,并可能更難維護(hù)。
這也解釋了為什么編寫(xiě)更少代碼的經(jīng)驗(yàn)法則是編寫(xiě)能夠起效的最簡(jiǎn)單的代碼。
極限編程闡明了兩個(gè)寫(xiě)簡(jiǎn)單代碼的黃金原則:
· 第一,以你認(rèn)為能夠起效的最簡(jiǎn)單的方法。不要搭建太多使人眼花繚亂的超級(jí)結(jié)構(gòu),不要搞花里胡哨的噱頭,只要有效就好。對(duì)新特征的代碼進(jìn)行單元檢測(cè)(所有特征都需要這一步)。
· 第二,也是極其重要的一點(diǎn),重構(gòu)系統(tǒng),使其在保留現(xiàn)有所有特征的情況下,盡可能使用最簡(jiǎn)單的代碼。遵循“有且僅有一次”原則和其他代碼質(zhì)量原則,使得系統(tǒng)盡可能地簡(jiǎn)單明了。
時(shí)刻記住,我們需要的不是最快捷的方法,而是最簡(jiǎn)單的結(jié)果。因此,首先將現(xiàn)有方法分解為多個(gè)部分,保留現(xiàn)有測(cè)試用例繼續(xù)運(yùn)行。其次,簡(jiǎn)單地修改其中一小部分方法,用于處理下一個(gè)測(cè)試用例。如此循環(huán)。
記住,簡(jiǎn)約是極致的優(yōu)雅。優(yōu)秀編程的本質(zhì)在于控制和消除復(fù)雜性。
永遠(yuǎn)不要讓代碼變得更糟糕
這可以說(shuō)是開(kāi)發(fā)人員的“希波克拉底誓言”。開(kāi)發(fā)人員常常被建議不要圖省事走捷徑,否則將會(huì)導(dǎo)致代碼質(zhì)量下降,變得更糟糕。
和醫(yī)療程序一樣,軟件工程程序具有入侵性和破壞性,其使用的工具和技術(shù)也可能是全新的、未經(jīng)檢測(cè)的(或隨意檢測(cè)的)。然而不同的是,軟件工程的實(shí)踐和采用的工具沒(méi)有得到類似醫(yī)療資格理事會(huì)或食品藥品管理局(FGA)這樣的組織的規(guī)范。因此,軟件工程開(kāi)發(fā)者有時(shí)會(huì)在尚未完全了解風(fēng)險(xiǎn)的情況下對(duì)“病人”——即軟件——進(jìn)行不必要的風(fēng)險(xiǎn)性操作。
在解決問(wèn)題的過(guò)程中,我們所做的有時(shí)會(huì)得不償失。Steve McConnell在其軟件工程經(jīng)典著作《代碼大全(Code Complete)》中提到,如果不解決問(wèn)題的根源,而僅僅局限于問(wèn)題的表面,往往是弊大于利的,開(kāi)發(fā)者會(huì)自我欺騙,讓自己相信這個(gè)問(wèn)題已經(jīng)解決了。
然而有時(shí)候這是很難的。遺留代碼增強(qiáng)了恰到好處地增加功能而又不損害代碼的難度。實(shí)際上,把“永遠(yuǎn)不要讓代碼變得更糟糕”改成“故意降低代碼質(zhì)量”更加符合事實(shí)。
是的。如果你不知道如何在保持代碼質(zhì)量不變的情況下更改代碼,那么就在更改之前告知團(tuán)隊(duì)其他成員。重點(diǎn)在于,你是故意降低代碼質(zhì)量的。
當(dāng)然,這并不能夠防范不好的代碼,但是可以給你一些時(shí)間來(lái)思考。經(jīng)驗(yàn)告訴我們,人們?cè)跓o(wú)法想到好的解決辦法時(shí),會(huì)停止思考,轉(zhuǎn)而做腦海中想到的第一件事。需要注意的是,我們并不是在要求獲得準(zhǔn)許或得到一個(gè)更好的結(jié)果。
“故意降低代碼質(zhì)量”的另一個(gè)優(yōu)點(diǎn)在于它可以防范在錯(cuò)誤的時(shí)間發(fā)生令人不悅的意外,并且使團(tuán)隊(duì)成員意識(shí)到可能出現(xiàn)的問(wèn)題。這樣,團(tuán)隊(duì)就可以很好地合作,處理這些問(wèn)題。
圖片來(lái)源:Unsplash/Maria Teneva
避免不必要的并發(fā)性
并發(fā)性是一把雙刃劍,應(yīng)該只在必要的時(shí)候使用。
如果源代碼是按順序執(zhí)行的,那么代碼更容易被理解和調(diào)試。但如果使用了并發(fā)性,代碼執(zhí)行可能會(huì)出現(xiàn)并行或不規(guī)律。這種執(zhí)行上的差異使得代碼調(diào)試變得非常困難。更不用說(shuō),它會(huì)以多種方式導(dǎo)致程序設(shè)計(jì)和執(zhí)行復(fù)雜化。由于實(shí)行不當(dāng)?shù)牟l(fā)性可能導(dǎo)致的問(wèn)題有:
· 競(jìng)爭(zhēng)條件(race conditions):出現(xiàn)預(yù)料之外的操作。
· 死鎖(deadlocks):表格被鎖定,需要等待同步操作推進(jìn)。
· 資源匱乏(resource starvation):操作被永久拒絕訪問(wèn)需要的資源。
世界上最臭名昭著的一個(gè)軟件災(zāi)難就是由并發(fā)行使用不當(dāng)造成的。Therac-25放射治療儀的一個(gè)編程問(wèn)題導(dǎo)致了4個(gè)人的死亡。
即便如此,現(xiàn)代編程語(yǔ)言和架構(gòu)還是提供了多種并發(fā)性工具。但是最終決定權(quán)還是在開(kāi)發(fā)者手上。開(kāi)發(fā)人員決定了如何、何時(shí)、何處使用并發(fā)性來(lái)達(dá)到最好的結(jié)果。
最后,不要囤積代碼
強(qiáng)迫性囤積,或者說(shuō)囤積障礙,特指一種過(guò)度獲取、無(wú)法或不愿丟棄大量物品,最終導(dǎo)致占用大量生活區(qū)域并帶來(lái)災(zāi)難或損害的行為模式。
如果開(kāi)發(fā)者有囤積障礙,他們會(huì)牢牢抓住有漏洞甚至是已經(jīng)廢棄的代碼不放。這樣的開(kāi)發(fā)者永遠(yuǎn)不會(huì)刪除任何代碼,也拒絕調(diào)動(dòng)代碼。而當(dāng)你去質(zhì)問(wèn)他們時(shí),他們會(huì)給出“我們總有一天可能會(huì)用到這個(gè)代碼”或“我需要這個(gè)代碼來(lái)執(zhí)行活動(dòng)X”,諸如此類的回答。
你是代碼囤積者嗎?你是否以沒(méi)有時(shí)間為借口而拒絕清理一團(tuán)糟的代碼?如果你的回答是肯定的,那么你就是一個(gè)代碼囤積者,你的工作就是一團(tuán)亂麻。
囤積是一種非理性行為。如果你不確定代碼的存在是否合理,可以對(duì)它進(jìn)行恰當(dāng)?shù)貥?biāo)記,以便讓你注意到它,并再稍后重新審視它。最后,定期清理無(wú)效的、不需要的代碼。
一個(gè)好的編程人員每天都在使自己的代碼變得更好,精益求精。他們的代碼質(zhì)量會(huì)隨著時(shí)間的增長(zhǎng)而提高。優(yōu)秀的編程人員總是留下比舊代碼更加簡(jiǎn)潔的遺留代碼,而不是一團(tuán)亂麻。他們的名譽(yù)被嵌在代碼中永久保留。
就像Robert Martin說(shuō)過(guò):真相只存在于代碼之中。
留言 點(diǎn)贊 關(guān)注
我們一起分享AI學(xué)習(xí)與發(fā)展的干貨
編譯組:王努銥、殷睿宣
相關(guān)鏈接:
https://medium.com/better-programming/how-to-write-less-code-and-get-more-done-40006282817d
如需轉(zhuǎn)載,請(qǐng)后臺(tái)留言,遵守轉(zhuǎn)載規(guī)范