版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
這個(gè)程序庫(kù)是其他人封裝的,拿過(guò)來(lái)用。按理說(shuō),我調(diào)用的這個(gè)函數(shù)邏輯也不是特別復(fù)雜,不應(yīng)該出現(xiàn)什么問(wèn)題。不過(guò),為了更快定位問(wèn)題,我還是打開(kāi)了這個(gè)程序庫(kù)的源代碼。經(jīng)過(guò)一番挖掘,我發(fā)現(xiàn)在這個(gè)函數(shù)底層實(shí)現(xiàn)中,出現(xiàn)了一個(gè)全局變量。分析之后,我發(fā)現(xiàn)正是這個(gè)全局變量引起了這場(chǎng)麻煩,因?yàn)樵谖业拇a執(zhí)行過(guò)程中,有別的程序會(huì)調(diào)用另外的函數(shù),修改這個(gè)全局變量的值,最終,導(dǎo)致了我的程序執(zhí)行失敗。從表面上看,我調(diào)用的這個(gè)函數(shù)和另外那個(gè)函數(shù)八竿子都打不到,但是,它們卻通過(guò)一個(gè)底層的全局變量,產(chǎn)生了相互的影響。這就是一類非常讓人頭疼的Bug。有人認(rèn)為這是全局變量使用不當(dāng)造成的,在Jaa中,甚至取消了全局變量,但類似的問(wèn)題并沒(méi)有因此減少,只是以不同面貌展現(xiàn)出來(lái)而已,比如,saic變量。那么造成這類問(wèn)題的真正原因是什么呢?真正原因就在于變量是可變的代代12345678classSample1privatestaticfinalDateFormatformatnewpublicString{returnformat.format(new}}如果你不熟悉JDKSimpleDateFormat,你可能會(huì)覺(jué)得這段代碼看上去還不錯(cuò)。然而,publicclassSample2publicStringgetCurrentDateText()DateFormatformat=newreturnformat.format(new556}兩段代碼最大的區(qū)別就在于,SimpleDateFormat哪里構(gòu)建。一個(gè)是被當(dāng)作了一個(gè)字SimpleDateFormat對(duì)象是否共享。為什么這個(gè)對(duì)象共享會(huì)有問(wèn)題呢?翻看format方法的源碼,你會(huì)發(fā)現(xiàn)這樣1這里的calendarSimpleDateFormat個(gè)類的一個(gè)字段,正是因?yàn)樵趂ormat程中修改了calendar字段,所以,它才會(huì)出問(wèn)題。我們來(lái)看看這種問(wèn)題是怎么出現(xiàn)的,就像下面這張圖看到A線程把變量的值修改成自己需要的這時(shí)發(fā)生線程切換,B線程開(kāi)始執(zhí)行,將變量的值修改成它所需要的線程切換回來(lái),A程繼續(xù)執(zhí)行,但此時(shí)變量已經(jīng)不是自己設(shè)置的值了,所以,執(zhí)行會(huì)回到SimpleDateFormat上,問(wèn)題是一樣的,calendar就是那個(gè)共享的變量。一個(gè)線程剛剛設(shè)置的值,可能會(huì)被另外一個(gè)線程修改掉,因此會(huì)造成結(jié)果的不正確。而在Sample2的寫(xiě)法中,通過(guò)每次創(chuàng)建一個(gè)新的SimpleDateFormat對(duì)象,二者之間的共享解那如果我還是想按照Sample1的寫(xiě)法寫(xiě),SimpleDateFormat這個(gè)庫(kù)應(yīng)該怎么改寫(xiě)呢?可能你會(huì)想,SimpleDateFormat的作者沒(méi)寫(xiě)好,如果換我寫(xiě),我就會(huì)給它加上一(synchronized)或者加上鎖(Lock)。你甚至都沒(méi)有注意,你輕易地將多線程的復(fù)雜性引入了進(jìn)來(lái)。還記得我在分離關(guān)注點(diǎn)那節(jié)討論的問(wèn)題嗎,多線程是另外一個(gè)關(guān)注點(diǎn),能少用,盡量少用。一個(gè)更好的辦法是將alenar變成局部變量,這樣一來(lái),不同線程之間共享變量的問(wèn)題就得到了根本的解決。但是,這類非常頭疼的問(wèn)題在函數(shù)式編程中卻幾乎不存在,這就依賴于函數(shù)式編程的不變性。函數(shù)式編程的不變性主要體現(xiàn)在值和純函數(shù)上。值,你可以將它理解為一個(gè)初始化之后就不再改變的量,換句話說(shuō),當(dāng)你使用一個(gè)值的時(shí)候,值是不會(huì)變的。純函數(shù),是符合下面兩點(diǎn)的函數(shù):把值和純函數(shù)合起來(lái)看,值保證不會(huì)顯式改變一個(gè)量,而純函數(shù)保證的是,不會(huì)隱式改變一個(gè)量。我們,函數(shù)式編程中的函數(shù)源自數(shù)學(xué)中的函數(shù)。在這個(gè)語(yǔ)境里,函數(shù)就是純函數(shù),一個(gè)函數(shù)計(jì)算之后是不會(huì)產(chǎn)生額外的改變的,而函數(shù)中用到的一個(gè)一個(gè)量就是值,它們是不會(huì)隨著計(jì)算改變的。所以,在函數(shù)式編程中,計(jì)算天然就是不變的。正是由于不變性的存在,我們面遇到的那些問(wèn)題也就不再是問(wèn)題了。一方面,如果你拿到一個(gè)量,這次的值是1,下一次它還是1,我們完全不用擔(dān)心它會(huì)改變。另一方面,我們調(diào)用一個(gè)函數(shù),傳進(jìn)去同樣的參數(shù),它保證給出同樣的結(jié)果,行為是完全可以預(yù)期的,不會(huì)碰觸到其他部分。即便是在多線程的情況下,我們也不必考慮同步的問(wèn)題,后續(xù)一系列的問(wèn)題也就不存在了。這與我們習(xí)慣的方式有著非常大的區(qū)別,因?yàn)閭鹘y(tǒng)方式的基礎(chǔ)是面向內(nèi)存單元的,改來(lái)改去甚至已經(jīng)成為了程序員的本能。所以,我們對(duì)outer=couer+1這種代碼習(xí)以為常,而初學(xué)編程的人總會(huì)覺(jué)得這在數(shù)學(xué)上是不成立的。在之前的討論中,我們,傳統(tǒng)的編程方式占優(yōu)的地方是執(zhí)行效率,而現(xiàn)如今,這個(gè)優(yōu)點(diǎn)則越來(lái)越不明顯,反而是因?yàn)榈教幙勺兌鴰?lái)了的問(wèn)題。相較之下,我們更應(yīng)該在現(xiàn)在的設(shè)計(jì)中,考慮借鑒函數(shù)式編程的思路,把不變性地應(yīng)用在我們的代碼之中。那怎么應(yīng)用呢?首先是值。我們可以編寫(xiě)不變類,就是對(duì)象一旦構(gòu)造出來(lái)就不能改變Java程序員最熟悉的不變類應(yīng)該就是String類,怎樣編寫(xiě)不變類呢如果需要有改變,返回一個(gè)新的對(duì)象,而不是修改已有字前面兩點(diǎn)可能還好理解,最后一點(diǎn),我們可以看一下JavaString類的rece方法簽1String ce(charoldChar,char在這里,我們會(huì)用一個(gè)新的字符(newChar)替換掉這個(gè)字符串中原有的回。這樣一來(lái),使用原來(lái)這個(gè)字符串的類并不用擔(dān)心自己的內(nèi)容會(huì)隨之變化。我們?cè)賮?lái)看純函數(shù)。編寫(xiě)純函數(shù)的重點(diǎn)是,不修改任何字段,也不調(diào)用修改字段內(nèi)容的方法。因?yàn)樵趯?shí)際的工作中,我們使用的大多數(shù)都是傳統(tǒng)的程序設(shè)計(jì)語(yǔ)言,而不是嚴(yán)格的函數(shù)式編程語(yǔ)言,不是所有用到的量都是值。所以,站在實(shí)用性的角度,如果要使用變量,就使用局部變量。還有一個(gè)實(shí)用性的編程建議,就是使用語(yǔ)法中不變的修飾符,比如,Java就盡可能多使用final,C/C++就多寫(xiě)const。無(wú)論是修飾變量還是方法,它們的主要作用就是讓編譯器提當(dāng)你有了用不變性思考問(wèn)題的角度,你會(huì)發(fā)現(xiàn)之前的很多編程習(xí)慣是極其糟糕的Java程序員最喜歡寫(xiě)的setter,它就是提供了一個(gè)接口,修改一個(gè)對(duì)象內(nèi)部的值不過(guò),純粹的函數(shù)式編程是很的,我們只能把編程原則設(shè)定為盡可能編寫(xiě)不變類和純函數(shù)。但僅僅是這么來(lái)看,你也會(huì)發(fā)現(xiàn),自己從前寫(xiě)的很多代碼,尤其是大量負(fù)責(zé)業(yè)務(wù)邏而正是不變性的優(yōu)勢(shì),有些新的程序設(shè)計(jì)語(yǔ)言默認(rèn)選項(xiàng)不再是變量,而是值。比如,Rust里,你這么的是一個(gè)值,因?yàn)橐坏┏跏蓟耍銓o(wú)法修改它1letresult=而如果你想一個(gè)變量,必須顯式地告訴編譯器1letmutresult=Java一個(gè)專門(mén)的Valhalla項(xiàng)目就是做這個(gè)的。你也看現(xiàn)在回過(guò)頭來(lái)看編程范式那一講里說(shuō)的約函數(shù)式編程,限制使用賦值語(yǔ)句,它是對(duì)程序中的賦值施加了約然而,這類問(wèn)題在函數(shù)式編程中并不存在。其中,重要的原因就是函數(shù)式編程的不變性。函數(shù)式編程的不變性主要體現(xiàn)在它的值和純函數(shù)上。深入學(xué)習(xí)函數(shù)式編程時(shí),你會(huì)遇到的與之相關(guān)的各種說(shuō)法:無(wú)副作用、無(wú)狀態(tài)、透明等等,其實(shí)都是在討論不變性。即便使用傳統(tǒng)的程序設(shè)計(jì)語(yǔ)言,我們也可以從中借鑒一些編程的方法。比如,編寫(xiě)不變經(jīng)過(guò)了這三講的介紹,相信你已經(jīng)對(duì)函數(shù)式編程有了很多認(rèn)識(shí),不過(guò),把設(shè)計(jì)中最常用的部分給你做了一個(gè)介紹,這遠(yuǎn)遠(yuǎn)不是函數(shù)式編程的全部。就算Jaa這種后期增補(bǔ)的函數(shù)式編程的語(yǔ)言,其中也包含了惰性求值、Opioal等諸多內(nèi)容,值得你去深入了解。不過(guò)我相信有了前面知識(shí)的鋪墊,你再去學(xué)習(xí)函數(shù)式編程其他相關(guān)內(nèi)容,難度系數(shù)就會(huì)降低一些。如果今天的內(nèi)容你只能記住一件事,那請(qǐng)記?。罕M量編寫(xiě)不變類和純函最后,請(qǐng)你去了解一下Event Sourcing,結(jié)合今天的內(nèi)容,談?wù)勀銓?duì)它的理解。感謝閱讀,如果你覺(jué)得這一講的內(nèi)容對(duì)你
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年宜賓市敘州區(qū)婦幼保健計(jì)劃生育服務(wù)中心第二次公開(kāi)招聘聘用人員備考題庫(kù)及答案詳解一套
- 廣西欽州市教育系統(tǒng)2026年“欽聚英才”浦北縣專場(chǎng)集中招聘急需緊缺人才備考題庫(kù)含答案詳解
- 2025年玉溪川洋產(chǎn)業(yè)發(fā)展有限公司招聘工作人員備考題庫(kù)及答案詳解一套
- 湛江市2025年事業(yè)單位公開(kāi)招聘高層次人才備考題庫(kù)附答案詳解
- 2025年蘇州工業(yè)園區(qū)勝浦實(shí)驗(yàn)小學(xué)教學(xué)輔助人員招聘?jìng)淇碱}庫(kù)及參考答案詳解1套
- 2025年欽北區(qū)長(zhǎng)灘鎮(zhèn)衛(wèi)生院招聘?jìng)淇碱}庫(kù)有答案詳解
- 珙縣事業(yè)單位2025年下半年公開(kāi)考核招聘工作人員的備考題庫(kù)及一套答案詳解
- 北海市海城區(qū)關(guān)心下一代工作委員會(huì)辦公室2025年編外工作人員招聘?jìng)淇碱}庫(kù)附答案詳解
- 2025年貴州鹽業(yè)(集團(tuán))安順有限責(zé)任公司公開(kāi)招聘工作人員5人備考題庫(kù)及完整答案詳解1套
- 寧晉縣泊陽(yáng)農(nóng)業(yè)發(fā)展服務(wù)有限公司2025年公開(kāi)招聘工作人員備考題庫(kù)及參考答案詳解1套
- 測(cè)繪安全生產(chǎn)作業(yè)規(guī)范
- 安全生產(chǎn)先進(jìn)評(píng)選方案
- 三一旋挖打斜樁施工方案
- 國(guó)開(kāi)《廣告調(diào)查與預(yù)測(cè)》形考作業(yè)1-4答案
- 別墅物業(yè)費(fèi)代繳合同協(xié)議2025年規(guī)定
- 2025年中級(jí)會(huì)計(jì)財(cái)務(wù)管理真題及答案
- 《人工智能+汽車(chē)技術(shù)與應(yīng)用》課程標(biāo)準(zhǔn)
- (正式版)DB65∕T 3955-2016 《馬流產(chǎn)沙門(mén)氏菌病防治技術(shù)規(guī)范》
- 軟件開(kāi)發(fā)外包合同協(xié)議
- 輸液空氣栓塞課件
- 護(hù)理角色定位
評(píng)論
0/150
提交評(píng)論