国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

函數(shù)式編程與面向?qū)ο缶幊蘙5]:編程的本質(zhì)

miracledan / 1127人閱讀

摘要:函數(shù)式編程與面向?qū)ο缶幊叹幊痰谋举|(zhì)之劍目錄編程的本質(zhì)讀到兩篇文章寫(xiě)的不錯(cuò)綜合摘錄一下復(fù)合是編程的本質(zhì)函數(shù)式程序員在洞察問(wèn)題方面會(huì)遵循一個(gè)奇特的路線。在面向?qū)ο缶幊讨校?lèi)或接口的聲明就是表面。

函數(shù)式編程與面向?qū)ο缶幊蘙5]:編程的本質(zhì)

之劍 2016.5.6 01:26:31

編程的本質(zhì)

讀到兩篇文章,寫(xiě)的不錯(cuò), 綜合摘錄一下

復(fù)合是編程的本質(zhì)

函數(shù)式程序員在洞察問(wèn)題方面會(huì)遵循一個(gè)奇特的路線。他們首先會(huì)問(wèn)一些似有禪機(jī)的問(wèn)題。例如,在設(shè)計(jì)一個(gè)交互式程序時(shí),他們會(huì)問(wèn):什么是交互?在實(shí)現(xiàn) 基于元胞自動(dòng)機(jī)的生命游戲時(shí),他們可能又去沉思生命的意義。秉持這種精神,我將要問(wèn):什么是編程?在最基本的層面,編程就是告訴計(jì)算機(jī)去做什么,例如『從 內(nèi)存地址 x 處獲取內(nèi)容,然后將它與寄存器 EAX 中的內(nèi)容相加』。但是即使我們使用匯編語(yǔ)言去編程,我們向計(jì)算機(jī)提供的指令也是某種有意義的表達(dá)式。假設(shè)我們正在解一個(gè)難題(如果它不難,就沒(méi)必要用計(jì)算 機(jī)了),那么我們是如何求解問(wèn)題的?我們把大問(wèn)題分解為更小的問(wèn)題。如果更小的問(wèn)題還是還是很大,我們?cè)倮^續(xù)進(jìn)行分解,以此類(lèi)推。最后,我們寫(xiě)出求解這些 小問(wèn)題的代碼,然后就出現(xiàn)了編程的本質(zhì):我么將這些代碼片段復(fù)合起來(lái),從而產(chǎn)生大問(wèn)題的解。如果我們不能將代碼片段整合起來(lái)并還原回去,那么問(wèn)題的分解就 毫無(wú)意義。

層次化分解與重新復(fù)合的過(guò)程

這個(gè)思維過(guò)程, 并非是受計(jì)算機(jī)的限制而產(chǎn)生,它反映的是人類(lèi)思維的局限性。我們的大腦一次只能處理很少的概念。生物學(xué)中被廣為引用的 一篇論文指出我們我們的大腦中只能保存 7± 2 個(gè)信息塊。我們對(duì)人類(lèi)短期記憶的認(rèn)識(shí)可能會(huì)有變化,但是可以肯定的是它是有限的。底線就是我們不能處理一大堆亂糟糟的對(duì)象或像蘭州拉面似的代碼。我們需要 結(jié)構(gòu)化并非是因?yàn)榻Y(jié)構(gòu)化的程序看上去有多么美好,而是我們的大腦無(wú)法有效的處理非結(jié)構(gòu)化的東西。我們經(jīng)常說(shuō)一些代碼片段是優(yōu)雅的或美觀的,實(shí)際上那只意味 著它們更容易被人類(lèi)有限的思維所處理。優(yōu)雅的代碼創(chuàng)造出尺度合理的代碼塊,它正好與我們的『心智消化系統(tǒng)』能夠吸收的數(shù)量相符。

那么,對(duì)于程序的復(fù)合而言,正確的代碼塊是怎樣的?它們的表面積必須要比它們的體積增長(zhǎng)的更為緩慢。我喜歡這個(gè)比喻,因?yàn)閹缀螌?duì)象的表面積是以尺寸 的平方的速度增長(zhǎng)的,而體積是以尺寸的立方的速度增長(zhǎng)的,因此表面積的增長(zhǎng)速度小于體積。代碼塊的表面積是是我們復(fù)合代碼塊時(shí)所需要的信息。代碼塊的體積 是我們?yōu)榱藢?shí)現(xiàn)它們所需要的信息。一旦代碼塊的實(shí)現(xiàn)過(guò)程結(jié)束,我們就可以忘掉它的實(shí)現(xiàn)細(xì)節(jié),只關(guān)心它與其他代碼塊的相互影響。在面向?qū)ο缶幊讨校?lèi)或接口 的聲明就是表面。在函數(shù)式編程中,函數(shù)的聲明就是表面。我把事情簡(jiǎn)化了一些,但是要點(diǎn)就是這些。

范疇論

在積極阻礙我們探視對(duì)象的內(nèi)部方面,范疇論具有非凡的意義。范疇論中的一個(gè)對(duì)象,像一個(gè)星云。對(duì)于它,你所知的只是它與其他對(duì)象之間的關(guān)系,亦即它 與其他對(duì)象相連接的箭頭。這就是 Internet 搜索引擎對(duì)網(wǎng)站進(jìn)行排名時(shí)所用的策略,它只分析輸入與輸出的鏈接(除非它受欺騙)。在面向?qū)ο缶幊讨校粋€(gè)理想的對(duì)象應(yīng)該是只暴露它的抽象接口(純表面, 無(wú)體積),其方法則扮演箭頭的角色。如果為了理解一個(gè)對(duì)象如何與其他對(duì)象進(jìn)行復(fù)合,當(dāng)你發(fā)現(xiàn)不得不深入挖掘?qū)ο蟮膶?shí)現(xiàn)之時(shí),此時(shí)你所用的編程范式的原本優(yōu) 勢(shì)就蕩然無(wú)存了。

讓我們暫時(shí)撇開(kāi)平臺(tái)、框架、技術(shù)、設(shè)計(jì)模式、對(duì)象思想、敏捷開(kāi)發(fā)論等。 追問(wèn)程序本質(zhì)。

布爾代數(shù)的邏輯體系

布爾代數(shù)起源于數(shù)學(xué)領(lǐng)域,是一個(gè)用于集合運(yùn)算和邏輯運(yùn)算的公式:〈B,∨,∧,? 〉。其中B為一個(gè)非空集合,∨,∧為定義在B上的兩個(gè)二元運(yùn)算,?為定義在B上的一個(gè)一元運(yùn)算。

通過(guò)布爾代數(shù)進(jìn)行集合運(yùn)算可以獲取到不同集合之間的交集、并集或補(bǔ)集,進(jìn)行邏輯運(yùn)算可以對(duì)不同集合進(jìn)行與、或、非。

在布爾代數(shù)上的運(yùn)算被稱(chēng)為AND(與)、OR(或)和NOT(非)。代數(shù)結(jié)構(gòu)要是布爾代數(shù),這些運(yùn)算的行為就必須和兩元素的布爾代數(shù)一樣(這兩個(gè)元素是TRUE(真)和FALSE(假))。亦稱(chēng)邏輯代數(shù).布爾(Boole,G.)為研究思維規(guī)律(邏輯學(xué))于1847年提出的數(shù)學(xué)工具.布爾代數(shù)是指代數(shù)系統(tǒng)B=〈B,+,·,′〉

它包含集合B連同在其上定義的兩個(gè)二元運(yùn)算+,·和一個(gè)一元運(yùn)算′,布爾代數(shù)具有下列性質(zhì):對(duì)B中任意元素a,b,c,有:







1.a(chǎn)+b=b+a, a·b=b·a.







2.a(chǎn)·(b+c)=a·b+a·c,







a+(b·c)=(a+b)·(a+c).







3.a(chǎn)+0=a,  a·1=a.







4.a(chǎn)+a′=1, a·a′=0.






公理化

在 1933 年,美國(guó)數(shù)學(xué)家 Edward Vermilye Huntington (1874-1952) 展示了對(duì)布爾代數(shù)的如下公理化:



交換律: x + y = y + x。







結(jié)合律: (x + y) + z = x + (y + z)。







Huntington等式: n(n(x) + y) + n(n(x) + n(y)) = x。


一元函數(shù)符號(hào) n 可以讀做"補(bǔ)"。

Herbert Robbins 接著擺出下列問(wèn)題: Huntington等式能否縮短為下述的等式,并且這個(gè)新等式與結(jié)合律和交換律一起成為布爾代數(shù)的基礎(chǔ)? 通過(guò)一組叫做 Robbins 代數(shù)的公理,問(wèn)題就變成了: 是否所有的 Robbins 代數(shù)都是布爾代數(shù)?

Robbins 代數(shù)的公理化:

交換律: x + y = y + x







結(jié)合律: (x + y) + z = x + (y + z)







Robbins等式: n(n(x + y") + n(x + n(y))) = x


這個(gè)問(wèn)題自從 1930 年代一直是公開(kāi)的,并成為 Alfred Tarski 和他的學(xué)生最喜好的問(wèn)題。

在 1996 年,William McCune 在 Argonne 國(guó)家實(shí)驗(yàn)室,建造在 Larry Wos、Steve Winker 和 Bob Veroff 的工作之上,肯定的回答了這個(gè)長(zhǎng)期存在的問(wèn)題: 所有的 Robbins 代數(shù)都是布爾代數(shù)。這項(xiàng)工作是使用 McCune 的自動(dòng)推理程序 EQP 完成的。

計(jì)算機(jī)程序的本質(zhì)

從本質(zhì)上來(lái)說(shuō), 程序就是一系列有序執(zhí)行的指令集合。 如何將指令集合組織成可靠可用可信賴(lài)的軟件(美妙的邏輯之塔), 這是個(gè)問(wèn)題。

程序 = 邏輯 + 控制。 what to do + when to do.

從編程角度來(lái)說(shuō), 開(kāi)發(fā)者應(yīng)對(duì)的就是邏輯, 邏輯的表達(dá)、組織和維護(hù)。 邏輯是事物自此及彼的合乎事物發(fā)展規(guī)律的序列。指令是邏輯的具體實(shí)現(xiàn)形式。

   邏輯成立的先決條件是合乎事物發(fā)展規(guī)律。 程序只能處理數(shù)值, 卻傳入了字符串, 就只能報(bào)錯(cuò)而無(wú)法繼續(xù); 當(dāng)處理海量數(shù)據(jù)時(shí), 若內(nèi)存不足, 就會(huì)導(dǎo)致程序崩潰; 若程序存在內(nèi)存泄露, 隨著時(shí)間的推移而耗盡內(nèi)存, 也會(huì)導(dǎo)致程序崩潰。 多個(gè)線程同時(shí)修改一個(gè)共享變量, 若不加控制, 就會(huì)因?yàn)椴煌€程執(zhí)行修改變量的時(shí)序的不確定導(dǎo)致該變量最終值的不確定。 這些就是程序執(zhí)行的發(fā)展規(guī)律。 要編寫(xiě)程序, 必定要先通悉這些規(guī)律。

規(guī)律的表現(xiàn)形式是:如果條件 (C1, C2, ..., Cn) 是產(chǎn)生結(jié)果 (R1, R2, ... , Rn) 的充分必要條件, 那么當(dāng) C1, C2, ..., Cn 任一不滿(mǎn)足條件時(shí), 都不可能產(chǎn)生結(jié)果 (R1, R2, ..., Rn) ; 反之, 若結(jié)果 (R1, R2, ..., Rn) 沒(méi)有出現(xiàn), 則必定是 C1, C2, ..., Cn 某一條件不滿(mǎn)足導(dǎo)致。 錯(cuò)誤和異常即是 C1, C2, ..., Cn 任一不滿(mǎn)足條件的表現(xiàn)。規(guī)律的性質(zhì)是必然的, 不存在可能之說(shuō); 只存在人們探索的是否足夠精確。編程開(kāi)發(fā)首先應(yīng)當(dāng)懂得程序執(zhí)行的規(guī)律, 然后才是實(shí)際的開(kāi)發(fā); 否則就會(huì)被程序的結(jié)果折騰得死去活來(lái)。

在通悉程序執(zhí)行規(guī)律之后, 程序需要解決如下問(wèn)題:

要表達(dá)什么邏輯

如何表達(dá)該邏輯;

如何維護(hù)該邏輯。

軟件的復(fù)雜性表現(xiàn)在如何表達(dá)和維護(hù)交互復(fù)雜的大型邏輯上

暫時(shí)先回到軟件的起點(diǎn), 回顧一下這一切是如何發(fā)生的。

最初, 人們使用物理的或邏輯的二進(jìn)制機(jī)器指令來(lái)編寫(xiě)程序, 嘗試著表達(dá)思想中的邏輯, 控制硬件計(jì)算和顯示, 發(fā)現(xiàn)是可行的;

接著, 創(chuàng)造了助記符 —— 匯編語(yǔ)言, 比機(jī)器指令更容易記憶;

再接著, 創(chuàng)造了編譯器、解釋器和計(jì)算機(jī)高級(jí)語(yǔ)言, 能夠以人類(lèi)友好自然的方式去編寫(xiě)程序, 在犧牲少量性能的情況下, 獲得比匯編語(yǔ)言更強(qiáng)且更容易使用的語(yǔ)句控制能力:條件、分支、循環(huán), 以及更多的語(yǔ)言特性: 指針、結(jié)構(gòu)體、聯(lián)合體、枚舉等, 還創(chuàng)造了函數(shù), 能夠?qū)⒁幌盗兄噶罘庋b成一個(gè)獨(dú)立的邏輯塊反復(fù)使用;

逐漸地,產(chǎn)生了面向過(guò)程的編程方法;

后來(lái), 人們發(fā)現(xiàn)將數(shù)據(jù)和邏輯封裝成對(duì)象, 更接近于現(xiàn)實(shí)世界, 且更容易維護(hù)大型軟件, 又出現(xiàn)了面向?qū)ο蟮木幊陶Z(yǔ)言和編程方法學(xué), 增加了新的語(yǔ)言特性: 繼承、 多態(tài)、 模板、 異常錯(cuò)誤。

為了不必重復(fù)開(kāi)發(fā)常見(jiàn)工具和任務(wù), 人們創(chuàng)造和封裝了容器及算法、SDK, 垃圾回收器, 甚至是并發(fā)庫(kù);

為了讓計(jì)算機(jī)語(yǔ)言更有力更有效率地表達(dá)各種現(xiàn)實(shí)邏輯, 消解軟件開(kāi)發(fā)中遇到的沖突, 還在語(yǔ)言中支持了元編程、 高階函數(shù), 閉包 等有用特性。

為了更高效率地開(kāi)發(fā)可靠的軟件和應(yīng)用程序, 人們逐漸構(gòu)建了代碼編輯器、 IDE、 代碼版本管理工具、公共庫(kù)、應(yīng)用框架、 可復(fù)用組件、系統(tǒng)規(guī)范、網(wǎng)絡(luò)協(xié)議、 語(yǔ)言標(biāo)準(zhǔn)等, 針對(duì)遇到的問(wèn)題提出了許多不同的思路和解決方案, 并總結(jié)提煉成特定的技術(shù)和設(shè)計(jì)模式, 還探討和形成了不少軟件開(kāi)發(fā)過(guò)程, 用來(lái)保證最終發(fā)布的軟件質(zhì)量。 盡管編寫(xiě)的這些軟件和工具還存在不少 BUG ,但是它們都“奇跡般地存活”, 并共同構(gòu)建了今天蔚為壯觀的軟件世界。

此外, 軟件還經(jīng)歷了“單機(jī)程序 => 多機(jī)程序 => 分布式程序” 的過(guò)程 , 多機(jī)聯(lián)網(wǎng)程序因?yàn)槎鄠€(gè)子系統(tǒng)的交互變得更加復(fù)雜。 這里不再贅述。

但請(qǐng)注意, 無(wú)論軟件發(fā)展到多么復(fù)雜的程度, 總有一群人, 在試圖從程序的本質(zhì)中探究軟件開(kāi)發(fā)的基本問(wèn)題, 他們?cè)噲D論證和確保程序的正確性、提煉軟件的基本屬性并進(jìn)行衡量; 程序的正確性本質(zhì)是邏輯學(xué)來(lái)保證的。 沒(méi)有邏輯學(xué), 程序根本就無(wú)法立足, 更不可能有今天的大規(guī)模應(yīng)用。

軟件開(kāi)發(fā)工具讓我們更有效率地創(chuàng)造邏輯、 遠(yuǎn)離語(yǔ)法錯(cuò)誤的困擾;

公共庫(kù)將常用的通用邏輯塊封裝成可反復(fù)使用的組件, 避免不必要的重復(fù)勞動(dòng);

設(shè)計(jì)模式體現(xiàn)的是如何可擴(kuò)展地解決常見(jiàn)的邏輯交互問(wèn)題;

應(yīng)用框架解決的是應(yīng)用的通用邏輯流的控制的問(wèn)題,讓開(kāi)發(fā)者更多地聚焦具體業(yè)務(wù)邏輯上;

開(kāi)發(fā)技術(shù)是在具體的應(yīng)用情境下按照既定總體思路去探究具體問(wèn)題解決的方法。

表達(dá)和維護(hù)大型邏輯

我們要解決的是更通用的問(wèn)題: 如何以更不易出錯(cuò)的方式去表達(dá)和維護(hù)大型邏輯 ?

表達(dá)和維護(hù)大型邏輯的終極訣竅就是: 將大型邏輯切分為容易消化的一小塊一小塊, “不急不忙地吃掉”。

在該方法的實(shí)踐中, 可以充分利用現(xiàn)有的開(kāi)發(fā)工具、公共庫(kù)、設(shè)計(jì)模式、應(yīng)用框架、開(kāi)發(fā)技術(shù)。

獨(dú)立無(wú)交互的大型邏輯或接口實(shí)現(xiàn)

獨(dú)立無(wú)交互的邏輯通常體現(xiàn)為公共庫(kù), 可以解決常用或公共的日常任務(wù), 對(duì)其他邏輯無(wú)任何依賴(lài)和交互, 即自足邏輯。

應(yīng)對(duì)獨(dú)立無(wú)交互的大型邏輯的首要方法是分解為若干的容易實(shí)現(xiàn)、測(cè)試和復(fù)用的小塊邏輯, 編寫(xiě)和嚴(yán)格測(cè)試。

其次是運(yùn)用成熟的編程模式去表達(dá)邏輯, 盡可能復(fù)用經(jīng)過(guò)嚴(yán)格測(cè)試的可靠的庫(kù)。

獨(dú)立無(wú)交互的大型邏輯通過(guò)合理的邏輯塊切分、嚴(yán)格的單元測(cè)試可以獲得充分的測(cè)試和可靠度。

獨(dú)立無(wú)交互的耗時(shí)長(zhǎng)的邏輯或接口實(shí)現(xiàn)

快速響應(yīng)的問(wèn)題: “用戶(hù)要求等待時(shí)間短” 與 “請(qǐng)求處理耗時(shí)長(zhǎng)” 之間的矛盾導(dǎo)致的。

解決獨(dú)立無(wú)交互的耗時(shí)長(zhǎng)的邏輯依然可以采用切分邏輯塊、嚴(yán)格的單元測(cè)試的做法使之更容易處理;

此外, 有兩種設(shè)計(jì)思路可以考慮: 并發(fā) 與 異步。

并發(fā)思路是將切分的相互獨(dú)立的邏輯塊分配給不同的控制線程中執(zhí)行, 從而降低請(qǐng)求處理時(shí)長(zhǎng); 并發(fā)方案獲得的性能提升取決于串行操作在總操作中的時(shí)間占比。

異步思路是“先響應(yīng), 后處理, 終通知” 的"先奏后斬"方案。

將一步分離成了三步, 為了讓用戶(hù)首先獲得初步的承諾, 再去履行承諾。 這樣做能讓用戶(hù)暫時(shí)地放心, 卻增加了新的問(wèn)題: 消息中間件組件的開(kāi)發(fā)與部署、異步消息發(fā)送與接收、編程模型的變化和適應(yīng)。如果整個(gè)過(guò)程運(yùn)作良好, 將會(huì)達(dá)到很好的體驗(yàn),容易為用戶(hù)接受。如果其中一步發(fā)生差錯(cuò), 就會(huì)導(dǎo)致各種問(wèn)題, 比如數(shù)據(jù)不一致, 消息堆積、 請(qǐng)求無(wú)法被處理。最終用戶(hù)等待時(shí)間并沒(méi)有降低, 反而使體驗(yàn)更加糟糕。 當(dāng)然, 如果成功率為 95%, 也是“可以接受”的, 這樣用戶(hù)可能會(huì)怪自己“運(yùn)氣不太好”, 而不會(huì)過(guò)多怪責(zé)系統(tǒng)的不完善。畢竟沒(méi)有任何事情能夠做到完美的地步。

并發(fā)與異步方案的調(diào)試難度和排查問(wèn)題都比同步方案增加不少。 每一種新的設(shè)計(jì)方案都會(huì)有其優(yōu)點(diǎn), 同時(shí)也會(huì)有其缺點(diǎn)。 權(quán)衡優(yōu)缺點(diǎn), 擇善而從之 。值得注意的是, 并發(fā)方案是針對(duì)服務(wù)端實(shí)際處理請(qǐng)求邏輯而言, 而異步方案是針對(duì)請(qǐng)求處理之前是否立即回復(fù)的方式。 并發(fā)與順序、 異步與同步兩兩組合, 可得到四種方式:

順序同步: 最初的編程模型

優(yōu)點(diǎn)是簡(jiǎn)單、安全、 容易維護(hù)和調(diào)試;

缺點(diǎn)是性能較低, 響應(yīng)時(shí)間和吞吐量都不高; 若請(qǐng)求處理時(shí)長(zhǎng)非常短, 采用順序同步的方案佳;

并發(fā)同步: 改進(jìn)的編程模型

優(yōu)點(diǎn)是通過(guò)并發(fā)提高服務(wù)端的處理速度和吞吐量, 但若請(qǐng)求處理耗時(shí)較長(zhǎng), 響應(yīng)時(shí)間仍然不高, 影響客戶(hù)端體驗(yàn);

若通過(guò)并發(fā)方案處理請(qǐng)求的時(shí)長(zhǎng)非常短, 或客戶(hù)端體驗(yàn)要求不高, 可以采用并發(fā)同步的方案;

順序異步: 改善客戶(hù)端體驗(yàn)的編程模型

優(yōu)點(diǎn)是提高了響應(yīng)時(shí)間和客戶(hù)端體驗(yàn), 由于其邏輯處理仍然采用順序方式, 請(qǐng)求處理時(shí)長(zhǎng)并未有改善, 因此吞吐量并沒(méi)有改善。 是一種較好的折衷方案;

若請(qǐng)求處理耗時(shí)較長(zhǎng), 影響客戶(hù)端體驗(yàn), 且請(qǐng)求處理邏輯復(fù)雜, 采用并發(fā)方案容易出錯(cuò)或難以并發(fā), 可采用順序異步方案;

并發(fā)異步: 同時(shí)改善客戶(hù)端體驗(yàn)和服務(wù)端處理速度

優(yōu)點(diǎn)是提高了響應(yīng)時(shí)間、客戶(hù)端體驗(yàn)和處理速度、吞吐量。

缺點(diǎn)是容易出錯(cuò), 且不易調(diào)試;

若客戶(hù)端對(duì)響應(yīng)體驗(yàn)要求較高, 請(qǐng)求處理邏輯簡(jiǎn)單(比如簡(jiǎn)單的數(shù)據(jù)拉取和匯總), 采用并發(fā)方式可有效提升處理速度, 可以采用并發(fā)異步方案;

邏輯塊之間的交互耦合與可擴(kuò)展性

軟件的復(fù)雜性真正體現(xiàn)在邏輯塊的持續(xù)長(zhǎng)久的交互耦合和可擴(kuò)展上。這是軟件開(kāi)發(fā)與維護(hù)中極具挑戰(zhàn)性的部分。

邏輯塊之間的交互耦合通常體現(xiàn)在三種情境:

操作順序的依賴(lài)。 比如資源更新操作必須在指定資源已經(jīng)創(chuàng)建的情況下進(jìn)行。

對(duì)共享有限資源的并發(fā)申請(qǐng)。 比如打印機(jī)只有兩臺(tái), 卻有多個(gè)應(yīng)用程序連接上去請(qǐng)求打印文檔;

對(duì)共享可變狀態(tài)的并發(fā)訪問(wèn)。 比如兩個(gè)操作同時(shí)要更新數(shù)據(jù)庫(kù)中的同一條記錄;

三種情境的復(fù)雜性均是由并發(fā)引起的。 假設(shè)所有操作都是串行進(jìn)行的, 邏輯塊的交互無(wú)非是“你方唱罷我登場(chǎng)”的次序控制, 而資源對(duì)單個(gè)請(qǐng)求通常是足夠的; 一旦采用了并發(fā)方案, 就難以控制邏輯塊的執(zhí)行次序和資源分配的具體情況了, 容易導(dǎo)致某資源對(duì)單個(gè)請(qǐng)求不足的情況, 從而阻塞多個(gè)請(qǐng)求的處理甚至死鎖。并發(fā)提升了應(yīng)用的性能, 卻增加了出錯(cuò)的風(fēng)險(xiǎn)和幾率。并發(fā)控制是大型邏輯交互的本質(zhì)性難點(diǎn)。并發(fā)控制的難點(diǎn)在于時(shí)序的合理控制和有效資源的合理分配。

對(duì)于 a 情境, 通常采用添加前置條件來(lái)求解, 在操作之前校驗(yàn)相關(guān)資源是否滿(mǎn)足、實(shí)體狀態(tài)是否合理, 實(shí)體之間的關(guān)聯(lián)是否正確; 若前置條件不滿(mǎn)足, 則直接返回錯(cuò)誤提示, 或者暫時(shí)掛起以備后續(xù)繼續(xù)執(zhí)行;

對(duì)于 b 情境, 需要?jiǎng)?chuàng)建一個(gè)可靠適用的資源分配算法 和資源分配模塊 , 應(yīng)用程序不再“自行”去拉取資源, 而是向資源分配模塊申請(qǐng)資源, 由資源分配模塊根據(jù)實(shí)際申請(qǐng)的整體情況及申請(qǐng)條件來(lái)決定如何分配資源;

對(duì)于 c 情境, 需要進(jìn)行安全的互斥訪問(wèn), 謹(jǐn)慎地控制。

邏輯塊之間的交互耦合應(yīng)該交給交互解耦模塊去完成, 而不是在自己的接口里實(shí)現(xiàn)。

也就是說(shuō), 只有交互解耦模塊知道所有接口之間的交互, 而接口只做自己知道的事情就可以了。否則, 接口 A 與接口 B 必須知道彼此究竟做了什么, 才能正確地做自己的事情。 假設(shè) 接口 A 和接口 B 都修改某個(gè)資源的狀態(tài)。 接口 A 在做某項(xiàng)操作執(zhí)行必須執(zhí)行 IF (ConditionX) do something ; DoMyOwnThing ; 接 口 B 也要根據(jù) A 的邏輯相應(yīng)地執(zhí)行 if (ConditionY) do anotherThing;DoMyOwnThing. 而程序員在維護(hù)和修改接口 A 的邏輯時(shí), 不一定知道接口 B 的邏輯與之相關(guān), 于是修改不可避免地破壞了接口 B 的邏輯。 耦合的接口數(shù)量越多, 或者耦合接口之間的耦合資源越多, 對(duì)后期維護(hù)和擴(kuò)展將是一個(gè)難以應(yīng)對(duì)的噩夢(mèng)。

對(duì)于邏輯塊之間的交互解耦, 或者通俗地說(shuō), 模塊解耦.

實(shí)現(xiàn)邏輯時(shí)的容錯(cuò)考慮

程序中的邏輯主要是三類(lèi):

獲取值: 從數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)或?qū)ο笾蝎@取值。 如果數(shù)據(jù)庫(kù)或網(wǎng)絡(luò)訪問(wèn)足夠穩(wěn)定的話(huà), 可以看成是簡(jiǎn)單的獲取值, 數(shù)據(jù)庫(kù)訪問(wèn)和網(wǎng)絡(luò)訪問(wèn)對(duì)獲取值是透明的;

檢測(cè)值: 檢測(cè)值是否合法, 通常是前置條件校驗(yàn)、 中間狀態(tài)校驗(yàn)和后置結(jié)果校驗(yàn), 根據(jù)檢測(cè)結(jié)果執(zhí)行“獲取值”或“設(shè)置值”的邏輯;

設(shè)置(拷貝)值: 設(shè)置數(shù)據(jù)庫(kù)、對(duì)象中的值; 或者發(fā)送數(shù)據(jù)和指令給網(wǎng)絡(luò)。如果數(shù)據(jù)庫(kù)或網(wǎng)絡(luò)訪問(wèn)足夠穩(wěn)定的話(huà), 可以看成是簡(jiǎn)單的設(shè)置值, 數(shù)據(jù)庫(kù)訪問(wèn)和網(wǎng)絡(luò)訪問(wèn)對(duì)設(shè)置值是透明的;

這三類(lèi)邏輯可以稱(chēng)為邏輯元。 具體業(yè)務(wù)邏輯就是基于物理的或邏輯的資源限制, 將邏輯元的組合封裝成邏輯塊, 有效控制邏輯塊的時(shí)序交互和資源分配。 時(shí)序控制不合理和資源缺乏導(dǎo)致錯(cuò)誤和異常。兩個(gè)程序同時(shí)更新一個(gè)共享變量, 如果時(shí)序不控制, 就會(huì)導(dǎo)致錯(cuò)誤的結(jié)果; 網(wǎng)絡(luò)通信錯(cuò)誤, 是因?yàn)榫W(wǎng)絡(luò)帶寬資源是有限的。

如何應(yīng)對(duì)錯(cuò)誤和異常 ? 防御性編程

預(yù)防錯(cuò)誤的方法就是進(jìn)行防御性編程, 進(jìn)行容錯(cuò)考慮。 多思考: 如果這一步發(fā)生錯(cuò)誤, 會(huì)導(dǎo)致什么問(wèn)題? 該如何做才能預(yù)防這個(gè)錯(cuò)誤? 如果難以預(yù)防, 該如何描述, 才能在出現(xiàn)錯(cuò)誤時(shí)更好地定位出這樣的錯(cuò)誤? 在出現(xiàn)錯(cuò)誤時(shí), 如何才能恢復(fù)到正常合法的狀態(tài) ? 如果無(wú)法程序自動(dòng)恢復(fù), 怎樣做才能讓手工處理更加簡(jiǎn)單 ?

要健壯地表達(dá)和維護(hù)大型邏輯, 首先系統(tǒng)整體架構(gòu)必須足夠穩(wěn)固可靠, 在開(kāi)發(fā)和維護(hù)過(guò)程中持續(xù)加固。 假設(shè)一棟建筑整體設(shè)計(jì)有問(wèn)題, 那么, 無(wú)論里面的房間裝飾得多么漂亮優(yōu)雅, 都會(huì)隨著建筑的坍塌而消亡。 這需要深入去探究所使用的應(yīng)用框架, 挖出可能的不可靠風(fēng)險(xiǎn), 并加以預(yù)防和控制。

在已確定的設(shè)計(jì)方案和業(yè)務(wù)邏輯的情況下, 如何編寫(xiě)B(tài)UG更少的代碼:

簡(jiǎn)明扼要的注釋 + 契約式/防御式編程 + 更短小的邏輯塊 + 復(fù)用公共庫(kù) + 嚴(yán)格測(cè)試

編寫(xiě)更少BUG程序的六條準(zhǔn)則:

在方法前面編寫(xiě)簡(jiǎn)明扼要的注釋?zhuān)?方法用途, 接收參數(shù), 返回值, 注意事項(xiàng), 作者, 時(shí)間。

契約式編程: 在方法入口處編寫(xiě)前置條件校驗(yàn),在方法出口處編寫(xiě)后置結(jié)果校驗(yàn) ;

防御式編程: 編程時(shí)嚴(yán)格校驗(yàn)參數(shù)和前置條件; 仔細(xì)考慮各種錯(cuò)誤與異常的定位和處理;

編寫(xiě)和保持短小邏輯塊, 易于為人的腦容量一次性處理, 容易測(cè)試;

復(fù)用經(jīng)過(guò)嚴(yán)格測(cè)試的可靠的公共庫(kù); 如果庫(kù)沒(méi)有經(jīng)過(guò)很好的測(cè)試,但有很好的用處, 幫助其添加測(cè)試;

對(duì)所編寫(xiě)的代碼, 如果不是邏輯元, 都要進(jìn)行嚴(yán)格測(cè)試。

關(guān)于作者: 陳光劍,江蘇東海人, 號(hào)行走江湖一劍客,字之劍。程序員,詩(shī)人, 作家

http://universsky.github.io/?

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/65873.html

相關(guān)文章

  • 編程函數(shù)編程

    摘要:聲明式編程一種編程范式,與命令式編程相對(duì)立。常見(jiàn)的聲明式編程語(yǔ)言有數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)言,正則表達(dá)式邏輯編程函數(shù)式編程組態(tài)管理系統(tǒng)等。函數(shù)式編程,特別是純函數(shù)式編程,嘗試最小化狀態(tài)帶來(lái)的副作用,因此被認(rèn)為是聲明式的。 編程范式與函數(shù)式編程 一、編程范式的分類(lèi) 常見(jiàn)的編程范式有:函數(shù)式編程、程序編程、面向?qū)ο缶幊獭⒅噶钍骄幊痰取T诿嫦驅(qū)ο缶幊痰氖澜纾绦蚴且幌盗邢嗷プ饔茫ǚ椒ǎ┑膶?duì)象(Class...

    noONE 評(píng)論0 收藏0
  • 函數(shù)編程之組合

    摘要:在函數(shù)式編程的組合中,我們是從右到左執(zhí)行的,上述的例子中我們借助函數(shù)實(shí)現(xiàn)組合,當(dāng)然,我們也可以用自己的方式實(shí)現(xiàn)。小結(jié)函數(shù)式編程隨著多核的發(fā)展,開(kāi)始再次出現(xiàn)在我們的視野中,有時(shí)候也會(huì)擔(dān)心過(guò)于吹捧函數(shù)式,反而落入俗套。 程序的本質(zhì)是什么?數(shù)據(jù)結(jié)構(gòu)+算法!!!我想這也是很多程序員給出的答案,我自己也認(rèn)可這一觀點(diǎn),當(dāng)我們了解了某一門(mén)編程語(yǔ)之后,接下來(lái)我們面對(duì)的往往是數(shù)據(jù)結(jié)構(gòu)和算法的學(xué)習(xí)。而現(xiàn)在...

    Jinkey 評(píng)論0 收藏0
  • JavaScript 函數(shù)編程(一)

    摘要:函數(shù)式編程的哲學(xué)就是假定副作用是造成不正當(dāng)行為的主要原因。函數(shù)組合面向?qū)ο笸ǔ1槐扔鳛槊~,而函數(shù)式編程是動(dòng)詞。尾遞歸優(yōu)化函數(shù)式編程語(yǔ)言中因?yàn)椴豢勺償?shù)據(jù)結(jié)構(gòu)的原因,沒(méi)辦法實(shí)現(xiàn)循環(huán)。 零、前言 說(shuō)到函數(shù)式編程,想必各位或多或少都有所耳聞,然而對(duì)于函數(shù)式的內(nèi)涵和本質(zhì)可能又有些說(shuō)不清楚。 所以本文希望針對(duì)工程師,從應(yīng)用(而非學(xué)術(shù))的角度將函數(shù)式編程相關(guān)思想和實(shí)踐(以 JavaScript 為...

    hoohack 評(píng)論0 收藏0
  • JavaScript 函數(shù)編程導(dǎo)論

    摘要:函數(shù)式編程導(dǎo)論從屬于筆者的前端入門(mén)與工程實(shí)踐。函數(shù)式編程即是在軟件開(kāi)發(fā)的工程中避免使用共享狀態(tài)可變狀態(tài)以及副作用。 JavaScript 函數(shù)式編程導(dǎo)論從屬于筆者的Web 前端入門(mén)與工程實(shí)踐。本文很多地方是講解函數(shù)式編程的優(yōu)勢(shì),就筆者個(gè)人而言是認(rèn)可函數(shù)式編程具有一定的好處,但是不推崇徹底的函數(shù)式編程化,特別是對(duì)于復(fù)雜應(yīng)用邏輯的開(kāi)發(fā)。筆者在應(yīng)用的狀態(tài)管理工具中就更傾向于使用MobX而不是...

    forrest23 評(píng)論0 收藏0
  • JavaScript函數(shù)編程(1):基本思想

    摘要:中的函數(shù)式編程思想匿名函數(shù)在函數(shù)式編程語(yǔ)言中,函數(shù)是可以沒(méi)有名字的,匿名函數(shù)通常表示可以完成某件事的一塊代碼。匿名函數(shù)中包含對(duì)的局部變量的引用,因此當(dāng)返回時(shí),的值被保留不會(huì)被垃圾回收機(jī)制回收,持續(xù)調(diào)用,將會(huì)改變的值。 1 函數(shù)式編程簡(jiǎn)介 函數(shù)式編程是和傳統(tǒng)命令式編程區(qū)分的一種編程思想,在函數(shù)式編程語(yǔ)言中,函數(shù)是第一類(lèi)的對(duì)象,也就是說(shuō),函數(shù) 不依賴(lài)于任何其他的對(duì)象而可以獨(dú)立存在,而在面向...

    時(shí)飛 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<