版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
滿天飛的還記得我們?cè)陂_篇詞里提到過的一個(gè)壞味道嗎?我們 下publicvoidapprove(finallongbookId)5這是一段對(duì)作品進(jìn)行審核的代碼,通過bookId,找到對(duì)應(yīng)的作品,接下來,將審核狀態(tài)設(shè)我當(dāng)時(shí)之所以注意到這段代碼,就是因?yàn)檫@里用了seter。seter往往是缺乏封裝的一種做法。對(duì)于缺乏封裝的壞味道,我們上節(jié)課已經(jīng)用了一講的篇幅在說,我提到,很多人在寫代碼時(shí),寫完字段就會(huì)利用IDE生成eter,實(shí)際情況往往是,生成geter的同時(shí),seter也生成了出來。seter同eter一樣,反映的都是對(duì)細(xì)節(jié)的。據(jù),修改是一個(gè)更的操作。我在《軟件設(shè)計(jì)之美》專欄里講函數(shù)式編程的不變性時(shí),曾經(jīng)專門討論過可變的數(shù)據(jù)會(huì)帶來許多問題,簡(jiǎn)言之,你不知道數(shù)據(jù)會(huì)在哪里被何人以什么方式修改,造成的結(jié)果是,別人的修改會(huì)讓你的代碼。與之相伴的還有各種衍生出來的問題,最常見的就是可變的數(shù)據(jù)是可怕,但是,比可變的數(shù)據(jù)更可怕的是,不可控的變化,而seter這種不可控的變化。把各種實(shí)現(xiàn)細(xì)節(jié)完全交給對(duì)這個(gè)類不了解的使用者去修改,沒有人會(huì)知道他會(huì)怎么改,所以,這種修改完全是不可控的。缺乏封裝再加上不可控的變化,在我個(gè)人心目中,setter幾乎是第一的壞味道在開篇詞里,我們針對(duì)代碼給出的調(diào)整方案是,用一個(gè)函數(shù)替代了setter,也就是把它用代代publicvoidapprove(finallongbookId)51classBook通過在Book類里引入了一個(gè)approve函數(shù),審核狀態(tài)1classBook2publicvoid{3this.reviewStatus45}作為這個(gè)類的使用者,你并不需要知道這個(gè)類到底是怎么實(shí)現(xiàn)的。更重要的是,這里的變化變得可控了。雖然審核狀態(tài)這個(gè)字段還是會(huì)修改,但你所有的修改都要通過幾個(gè)函數(shù)作為。有任何業(yè)務(wù)上的調(diào)整,都會(huì)發(fā)生在類的內(nèi)部,只要保證接口行為不變,就不會(huì)影響到其它的代碼。setter破壞了封裝,相信你對(duì)這點(diǎn)已經(jīng)有了一定的理解。不過,有時(shí)候你會(huì)說,我這setter只是用在初始化過程中,而并不需要在使用的過程去調(diào)用,就像下面這樣Bookbook=new實(shí)際上,對(duì)于這種只在初始化中使用的代碼,壓根沒有必要以setter式存在,真正需1Bookbook=newBook(bookId,title,消除setter有一種專門的重構(gòu)手法,叫做移除設(shè)值函數(shù)(RemoveSettingMethod)??偠灾瑂etter是完全沒有必要存在的。在今天的軟件開發(fā)中,人們?yōu)榱撕?jiǎn)化代碼的編寫做出了各種努力,用DE生成的代碼是一種,還有一種常見的做法就是,通過工具和框架生成相應(yīng)代碼的。在Jaa世界中,Lomok就是這樣的一種程序庫(kù),它可以在編譯的過程中生成相應(yīng)的代碼,而我們需要做的,只是在代碼上加上對(duì)應(yīng)的Anoaion。它最大的優(yōu)點(diǎn)是不礙眼,也就是不會(huì)產(chǎn)生大量可以看見的代碼。因?yàn)樗拇a是在編譯階段生成的,所以,那些生成的代碼在源碼級(jí)別上是不存在的。下面就是一個(gè)例子:classBookprivateBookIdprivateStringprivateString7這里的@Getter表示為這個(gè)類的字段生成getter,相應(yīng)地,@Setter表示生成setter。也是因?yàn)檫@些Annotation的存在,讓代碼看上去清爽了不少。所以,像Lombok這樣的不過,說的是,不寫seter的代碼并不代表沒有seter。因?yàn)锧eter的存在,其它代碼還是可以調(diào)用這個(gè)類的seter,存在的問題并不會(huì)改變。所以,一個(gè)更好的做法是禁用@eter。下面是lombo.coig的配置,通過它,我們就可以禁用@eter了:lombok.setter.flagUsage=lombok.data.flagUsage=你或許注意到了,這里除了@Setter,我還禁用了@Data,這是Lombok中另外一個(gè)Annotation,表示的是同時(shí)生成gettersetter。既然我們禁用@Setter為了防止生成setter,當(dāng)然也要禁用@Data了。我們使用setter,一個(gè)重要的原因就是它了數(shù)據(jù),我們前面,數(shù)據(jù)造成的問題就在于數(shù)據(jù)的修改,進(jìn)而導(dǎo)致出現(xiàn)難以預(yù)料的Bug。在上面的代碼中,我們把setter封裝成一個(gè)個(gè)的函數(shù),實(shí)際上是把不可控的修改限制在一個(gè)有限的范圍內(nèi)。那么,這個(gè)思路再進(jìn)一步的話,如果我們的數(shù)據(jù)壓根不讓修改,犯下各種低級(jí)錯(cuò)誤的機(jī)會(huì)就進(jìn)一步降低了。沒錯(cuò),在這種思路下,可變數(shù)據(jù)(Mutableata)就成了一種壞味道,這是MarinFwler在新版《重構(gòu)》里增加的壞味道,它反映著整個(gè)行業(yè)對(duì)于編這種想法源自函數(shù)式編程這種編程范式。在函數(shù)式編程中,數(shù)據(jù)是建立在不改變的基礎(chǔ)上的,如果需要更新,就產(chǎn)生一份新的數(shù)據(jù)副本,而舊有的數(shù)據(jù)保持不變。隨著函數(shù)式編程在軟件開發(fā)領(lǐng)域中的地位不斷提高,人們對(duì)于不變性的理解也越發(fā)深刻,不變性有效地解決了可變數(shù)據(jù)產(chǎn)生的各種問題。所以,MartinFowler在《重構(gòu)》第二版里新增了可變數(shù)據(jù)作為一種壞味道,這其實(shí)反映了行業(yè)的理解也是在逐漸推進(jìn)的。不過,MartinFowler對(duì)于可變數(shù)據(jù)給出的解決方案,基本上是限制對(duì)于數(shù)據(jù)的更新,降低其風(fēng)險(xiǎn),這與我們前面提到的對(duì)setter的封裝如出一解決可變數(shù)據(jù),還有一個(gè)解決方案是編寫我在《軟件設(shè)計(jì)之美》專欄中已經(jīng)講過函數(shù)式編程的不變性,其中的關(guān)鍵點(diǎn)就是設(shè)計(jì)不變類。Java中的String類就是一個(gè)不變類,比如,如果我們把字符串中的一個(gè)字符替換成另一個(gè)字符,String類給出的函數(shù)簽名是這樣的:1String ce(charoldChar,char所有的字段只在構(gòu)造函數(shù)中初始所有的方法都是純函數(shù)如果需要有改變,返回一個(gè)新的對(duì)象,而不是修改已有字回過頭來看我們之前改動(dòng)的“用構(gòu)造函數(shù)setter”的代碼,其實(shí)就是朝著這個(gè)方向在邁進(jìn)。如果按照這個(gè)思路改造我們前面提到的approve函數(shù),同樣也可以:classBookpublicvoidapprove()returnnewBook(...,ReviewStatus.APPROVED, 5這里,我們創(chuàng)建出了一個(gè)“其它參數(shù)和原有book象一模一樣,只是審核狀態(tài)變成了APPROVED”的對(duì)象。JDK演化中,我們可以看到一個(gè)很明顯的趨勢(shì),新增的類越來越多地采用了不變類的設(shè)計(jì),比如,用來表示時(shí)間的類。原來的Date類里面還有各種setter,而新增的LocalDateTime一旦初始化就不會(huì)再修改了。如果要操作這個(gè)對(duì)象,則會(huì)產(chǎn)生一個(gè)新的1LocalDateTimetwoDaysLater=一個(gè)更實(shí)用的做法是,區(qū)分類的性質(zhì)。我《 軟件設(shè)計(jì)之美》中講DDD的戰(zhàn)術(shù)設(shè)計(jì)時(shí)提到過,我們最要識(shí)別的對(duì)象分成兩種,實(shí)體和值對(duì)象。實(shí)體對(duì)象要限制數(shù)據(jù)變化,如果你還想進(jìn)一步提升自己對(duì)于不變性的理解,我們可以回到函數(shù)式編程這個(gè)編程范式的本質(zhì),它其實(shí)是對(duì)程序中的賦值進(jìn)行了約束?;谶@樣的理解,連賦值本身其實(shí)都會(huì)被歸入到壞味道的提示,這才是真正很多人編程習(xí)慣的一點(diǎn)。不過,我們現(xiàn)在看到,越來越多的語言中開始引入值類型,也就是初始化之后便不再改變的值,比如,Jaa的lhalla項(xiàng)目,更有甚者,像Rust這樣的語言中,缺省都是值類型,而如果你需要一個(gè)可以賦值的變量,反而要去專門的。MartinFowler在《重構(gòu)》中還提到一個(gè)與數(shù)據(jù)相關(guān)的壞味道:全局?jǐn)?shù)據(jù)(Global今天我們又講了一類與很多人編程習(xí)慣不符的壞味道:可變的數(shù)可變數(shù)據(jù)最直白的體現(xiàn)就是各種setter。setter方面破壞了封裝,另一方面它會(huì)帶來不SettingMethod),將變化限制在一定的范圍之內(nèi)。可變數(shù)據(jù)是《重構(gòu)》第二版新增的壞味道,這其實(shí)反映了軟件開業(yè)的一種進(jìn)步,它背后的思想是函數(shù)式編程所體現(xiàn)的不變性。解決可變數(shù)據(jù),式是限制其變化,另一種在實(shí)踐中,完全消除可變數(shù)據(jù)是很有的。所以,一個(gè)實(shí)際的做法是,區(qū)分類的性質(zhì)。如果
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年度裝飾裝修工程安裝合同
- 2024年工程材料供應(yīng)與驗(yàn)收合同
- 公司員工檢討書
- 2024年度新能源發(fā)電設(shè)備采購(gòu)與銷售合同
- 2024年度W公司環(huán)保服務(wù)合同協(xié)議書
- 2024年建筑公司員工聘用合同
- 2024年度網(wǎng)絡(luò)通訊工程安全文明施工管理協(xié)議
- 2024年大型油田勘探開發(fā)合作合同(海外)
- 2024年度某航空公司飛機(jī)采購(gòu)合同
- 2024年度區(qū)塊鏈應(yīng)用合作協(xié)議
- 暖通工程師面試試題(含答案)
- 行政服務(wù)中心窗口工作人員手冊(cè)
- 最新患者用藥情況監(jiān)測(cè)
- 試樁施工方案 (完整版)
- ESTIC-AU40使用說明書(中文100版)(共138頁)
- 河北省2012土建定額說明及計(jì)算規(guī)則(含定額總說明)解讀
- 中工商計(jì)算公式匯總.doc
- 深圳市建筑裝飾工程消耗量標(biāo)準(zhǔn)(第三版)2003
- 《初中英語課堂教學(xué)學(xué)困生轉(zhuǎn)化個(gè)案研究》開題報(bào)告
- 恒溫箱PLC控制系統(tǒng)畢業(yè)設(shè)計(jì)
- 176033山西《裝飾工程預(yù)算定額》定額說明及計(jì)算規(guī)則
評(píng)論
0/150
提交評(píng)論