10 個(gè)有用的軟件開發(fā)原則
?△點(diǎn)擊上方“Python貓”關(guān)注 ,回復(fù)“1”領(lǐng)取電子書

我總結(jié)了一些軟件開發(fā)原則。在這些原則中,大多數(shù)都是以簡(jiǎn)化系統(tǒng)為核心。在我看來(lái),簡(jiǎn)單的系統(tǒng)會(huì)更可靠,更容易修改,而且一般更容易使用。當(dāng)觀念發(fā)生改變時(shí),我希望更新它們。
我把這一點(diǎn)排第一,是因?yàn)槲艺J(rèn)為它是最重要、最強(qiáng)大的原則之一。
你可能在定義類型時(shí)聽到過(guò)這個(gè)詞,但其實(shí)這個(gè)原則適用于所有與表示數(shù)據(jù)相關(guān)的地方——例如數(shù)據(jù)庫(kù)設(shè)計(jì)。
它不僅可以減少系統(tǒng)的狀態(tài)數(shù)量(從而變得更簡(jiǎn)單),還能減少無(wú)效狀態(tài)的數(shù)量!你的系統(tǒng)不需要處理這些無(wú)效狀態(tài),因?yàn)樗鼈冊(cè)谀愕某绦蛑袑?shí)際上是不可表示的。
這不只是一個(gè)小技巧,它可以極大簡(jiǎn)化你的系統(tǒng),并防止出現(xiàn)各種類型的 bug。這有一些例子。
https://kevinmahoney.co.uk/articles/applying-misu/
對(duì)數(shù)據(jù)施加一致性規(guī)則,減少了系統(tǒng)需要處理的狀態(tài)數(shù)量。這是從上一個(gè)原則派生而來(lái)的。
這里說(shuō)的是一致性的普遍含義:即數(shù)據(jù)遵循某些規(guī)則,并且在任意時(shí)刻都始終遵循這些規(guī)則。這一定義與 ACID 有關(guān),但不要與 CAP 混淆起來(lái)了。
規(guī)則可以是任何東西,例如,你的信用永遠(yuǎn)不能變成負(fù)數(shù),或者私密的帖子不應(yīng)該被其他人看到。它不僅限于外鍵或惟一索引,盡管它們也是有效的規(guī)則。
和數(shù)據(jù)庫(kù)一樣,應(yīng)用程序也可以通過(guò)使用 ACID 事務(wù)來(lái)加強(qiáng)一致性。如果能在數(shù)據(jù)庫(kù)級(jí)別強(qiáng)制保持一致性是最好的,但在實(shí)際中,對(duì)稍微復(fù)雜一點(diǎn)的東西來(lái)說(shuō),這樣做并不常見。
任何限制或損害一致性的行為都會(huì)導(dǎo)致復(fù)雜性。這就引出了以下這些實(shí)用的建議:
讓系統(tǒng)更簡(jiǎn)單:
更少的數(shù)據(jù)庫(kù) (理想情況下是一個(gè))
規(guī)范化,減少冗余數(shù)據(jù)
一個(gè)“好的”數(shù)據(jù)庫(kù)設(shè)計(jì)
ACID 事務(wù)
更多的數(shù)據(jù)約束
讓系統(tǒng)更復(fù)雜:
多個(gè)數(shù)據(jù)庫(kù)
冗余或非正規(guī)化數(shù)據(jù)
糟糕的數(shù)據(jù)庫(kù)設(shè)計(jì)
較少(或沒(méi)有)數(shù)據(jù)約束
當(dāng)然,有時(shí)候讓系統(tǒng)變復(fù)雜也是有正當(dāng)理由的,我并不想讓復(fù)雜性變成一個(gè)“骯臟的”詞。請(qǐng)參閱后面的一個(gè)原則“殺雞不要用牛刀”。
我認(rèn)為這個(gè)原則是當(dāng)今軟件工程中最被低估的原則之一。一致性問(wèn)題經(jīng)常被忽視。很多問(wèn)題,我敢說(shuō)大多數(shù)問(wèn)題,基本上都是一致性問(wèn)題——數(shù)據(jù)不符合某些期望。
參見附錄,了解不一致性是如何導(dǎo)致復(fù)雜性的。
https://kevinmahoney.co.uk/articles/my-principles-for-building-software/#appendix-a-inconsistency-results-in-complexity
這個(gè)問(wèn)題,“代碼還是數(shù)據(jù)?”,哪一個(gè)在 10 年后更有可能繼續(xù)存在。
代碼可以被丟掉重寫,但數(shù)據(jù)很少會(huì)這樣。
數(shù)據(jù)比代碼更重要。代碼的唯一目的是轉(zhuǎn)換數(shù)據(jù)。
在設(shè)計(jì)新系統(tǒng)時(shí),最好先從數(shù)據(jù)庫(kù)和數(shù)據(jù)結(jié)構(gòu)開始,并在此基礎(chǔ)上開發(fā)代碼。要考慮可以在數(shù)據(jù)上施加的約束并實(shí)施它們,理想情況下是通過(guò)表示數(shù)據(jù)的方式進(jìn)行的。
代碼設(shè)計(jì)是數(shù)據(jù)設(shè)計(jì)的下一步。數(shù)據(jù)模型越簡(jiǎn)單、越一致,代碼就會(huì)越簡(jiǎn)單。
你們把流程圖給我看,但把表藏起來(lái),我就一頭霧水。你們把表給我看,通常我就不需要你們的流程圖,它們會(huì)不言自明。—— Fred Brooks
糟糕的程序員關(guān)心代碼。好的程序員關(guān)心數(shù)據(jù)結(jié)構(gòu)和它們之間的關(guān)系。—— Linux 之父 Linus Torvalds
這是軟件開發(fā)人員最常犯的錯(cuò)誤。
這個(gè)原則是說(shuō),當(dāng)你在做需要付出復(fù)雜性代價(jià)的權(quán)衡時(shí),要確保權(quán)衡的必要性得到經(jīng)驗(yàn)證據(jù)的支持。
常見錯(cuò)誤:
試圖構(gòu)建一個(gè)復(fù)雜的“可伸縮”系統(tǒng),可以伸縮到你可能永遠(yuǎn)都不需要的規(guī)模。
在不考慮需求或成本的情況下,讓服務(wù)盡可能地小。
在非性能瓶頸的地方優(yōu)化性能,增加不一致性或復(fù)雜性。
建議:
盡可能從最簡(jiǎn)單、最正確的系統(tǒng)開始
對(duì)性能進(jìn)行度量
如果不能解決實(shí)際問(wèn)題,就不要付出復(fù)雜性代價(jià)或違反其他原則。
有些優(yōu)化可以不進(jìn)行度量,因?yàn)樗鼈兊某杀痉浅5突驗(yàn)榱恪@纾瑸榱吮WC你想要執(zhí)行的操作具有你想要的性能,使用正確的數(shù)據(jù)結(jié)構(gòu)。
的確,有時(shí)候經(jīng)驗(yàn)本身就能告訴你是否做出了正確的權(quán)衡。但如果你能證明,那就更好了。
當(dāng)你必須做出選擇時(shí),請(qǐng)選擇正確性和簡(jiǎn)單性,而不是性能。
在某些情況下,正確而簡(jiǎn)單的代碼是性能最好的代碼!
真正的問(wèn)題是程序員在錯(cuò)誤的地方和錯(cuò)誤的時(shí)間花了太多的時(shí)間在擔(dān)心效率上。過(guò)早優(yōu)化是編程中所有(或者至少是大部分)罪惡的根源。——計(jì)算機(jī)科學(xué)家 Donald Knuth
也就是避免為了讓系統(tǒng)的一部分變得更簡(jiǎn)單,而導(dǎo)致整個(gè)系統(tǒng)變得更復(fù)雜。
這種交換通常是不平等的。追求局部的簡(jiǎn)單性會(huì)導(dǎo)致全局復(fù)雜性的增加,而且是數(shù)量級(jí)的。
例如,使用較小的服務(wù)可以讓這些服務(wù)變得更簡(jiǎn)單,但一致性的降低和對(duì)更多進(jìn)程間通信的需求讓系統(tǒng)變得更加復(fù)雜。
有時(shí)候事情本身就很復(fù)雜,你不能把問(wèn)題簡(jiǎn)單化。
任何這樣的嘗試都只會(huì)讓系統(tǒng)變得更加復(fù)雜。
深入理解一小部分技術(shù)要比只是表面理解很多技術(shù)好。
更少的技術(shù)意味著更少的東西要學(xué)習(xí)和更少的運(yùn)維復(fù)雜性。
不要太關(guān)心技術(shù)的復(fù)雜細(xì)節(jié),因?yàn)槟憧梢噪S時(shí)查閱它們。你要學(xué)習(xí)底層的基本概念。
技術(shù)會(huì)變化,概念卻是永恒的。你學(xué)到的概念將被用在更新的技術(shù)中,你就可以更快地學(xué)會(huì)新技術(shù)。
例如,不要太關(guān)注 React、Kubernetes、Haskell、Rust 的表面細(xì)節(jié)。
重點(diǎn)學(xué)習(xí):
純函數(shù)式編程
關(guān)系型模型
規(guī)范的方法
邏輯編程
代數(shù)數(shù)據(jù)類型
類型類 (通用的和特定的)
借位檢查器 (仿射 / 線性類型)
依賴類型
Curry-Howard 同構(gòu)
宏
同像性(Homoiconicity)
VirtualDOM
線性回歸
......
有時(shí)候,具有一致性的代碼比“正確”的代碼更重要。如果你想要改變代碼庫(kù)中某些代碼的行為,就要修改它所有的實(shí)例。否則的話,就只能忍受。
代碼的可讀性更多地與一致性(而不是簡(jiǎn)單性)有關(guān)。人們通過(guò)模式識(shí)別來(lái)理解代碼,所以請(qǐng)重復(fù) (和記錄) 模式!
如果你和隊(duì)友之間的共同原則越多,就能越好地在一起工作,而且你會(huì)越喜歡和他們?cè)谝黄鸸ぷ鳌?/p>
這是我能想到的最簡(jiǎn)單的例子,希望能毫不費(fèi)力地與現(xiàn)實(shí)問(wèn)題聯(lián)系起來(lái)。
假設(shè)一個(gè)數(shù)據(jù)庫(kù)有兩個(gè)布爾變量 x 和 y,你的應(yīng)用程序有一個(gè)規(guī)則,即 x = y,可以通過(guò)使用一個(gè)事務(wù)修改這兩個(gè)變量來(lái)執(zhí)行這個(gè)規(guī)則。
如果這個(gè)規(guī)則被正確執(zhí)行,那么數(shù)據(jù)只有兩種狀態(tài):(x = True,y = True) 或 (x = False,y = False)。
基于這個(gè)規(guī)則的函數(shù)“toggle”就非常簡(jiǎn)單。你可以讀取其中一個(gè)值,并將兩個(gè)值都設(shè)置為反向值。
現(xiàn)在,假設(shè)你將這兩個(gè)變量放到不同的數(shù)據(jù)庫(kù)中,并且不能再被一起修改,那么會(huì)發(fā)生什么?
因?yàn)槟悴荒艽_保 x = y 的一致性,所以數(shù)據(jù)可以有兩種以上的狀態(tài):(x = True,y = False) 或 (x = False,y = True)。
如果你的系統(tǒng)處于這些狀態(tài)中的一種,你應(yīng)該使用哪個(gè)值?
當(dāng)處于其中的一種狀態(tài)時(shí),“toggle”函數(shù)的行為是怎樣的?
在寫入新值時(shí),如何確保兩次寫入都成功?
這些問(wèn)題沒(méi)有正確的答案。
當(dāng)然,如果我們一開始就遵循“剔除無(wú)效狀態(tài)”的原則,那么將只有一個(gè)變量!
原文鏈接:https://kevinmahoney.co.uk/articles/my-principles-for-building-software/

近期熱門文章推薦:

