色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

重構(gòu),讓人快樂讓人苦

  重構(gòu),是編寫代碼必須要面對(duì)的一項(xiàng)操作,同時(shí)也應(yīng)該是程序員樂于實(shí)踐的一項(xiàng)內(nèi)容。不論是邏輯實(shí)現(xiàn)還是設(shè)計(jì)過程,乃至整個(gè)分層結(jié)構(gòu),我們都可能面臨并且實(shí)施重構(gòu)。這篇文章不會(huì)告訴您什么是重構(gòu),如何去優(yōu)美的重構(gòu)等等的理論,只想和大家分享一些感受,并且探討一些問題。最近的兩周,我一直對(duì)我們團(tuán)隊(duì)的一個(gè)子業(yè)務(wù)框架做重構(gòu)的工作,很多地方讓我感到很痛苦,于是便有了這篇文章。

  牽一發(fā)而動(dòng)全身的根源在哪里

  當(dāng)我打開解決方案,查看代碼的時(shí)候,我們會(huì)發(fā)現(xiàn)很多問題,比如冗余的代碼,性能低下的邏輯實(shí)現(xiàn)等等,但是當(dāng)我著手去改造的時(shí)候,潛意識(shí)告訴我整個(gè)似乎不能動(dòng),牽扯的面太廣了。更改一個(gè)小地方,上下一串都要做相應(yīng)的調(diào)整,這當(dāng)然不是我想要看到的。大范圍的調(diào)整會(huì)直接影響系統(tǒng)的穩(wěn)定性,帶來潛在的危險(xiǎn),同時(shí)會(huì)增加測試團(tuán)隊(duì)的負(fù)擔(dān);在版本控制方面會(huì)造成線上和線下版本在同一內(nèi)容的巨大差異,版本更新的時(shí)候拿什么來保證一套幾乎全新的代碼替換線上系統(tǒng)是正確的選擇呢?因?yàn)楹芏鄦栴}只有在最真實(shí)的環(huán)境才能被暴露出來。

  這樣的修改,修改成本無疑是巨大的,因?yàn)槲覀兤谕薷牡闹皇悄且恍K代碼而已。大范圍的代碼調(diào)整,同時(shí)也伴隨著單元測試代碼的調(diào)整。測試團(tuán)隊(duì)如果因此來重新走測試用例,那么付出的辛苦可想而知。

  我要做的是重構(gòu)而不是重寫,造成這種現(xiàn)象的原因在哪里呢?

  整個(gè)解決方案具有相對(duì)完整的分層結(jié)構(gòu),DAO層、實(shí)體層、業(yè)務(wù)邏輯層。實(shí)體層也對(duì)數(shù)據(jù)實(shí)體和業(yè)務(wù)實(shí)體做了分別定義。但是進(jìn)行業(yè)務(wù)實(shí)現(xiàn)的時(shí)候我們并沒有進(jìn)行有效的隔離和代碼的職責(zé)劃分。

  很多代碼在處理業(yè)務(wù)邏輯的時(shí)候直接調(diào)用DAO,然后使用返回的數(shù)據(jù)組織業(yè)務(wù)實(shí)體。當(dāng)我們的業(yè)務(wù)實(shí)體需要按照領(lǐng)域劃分為兩個(gè)或者更多的層次的時(shí)候,結(jié)果會(huì)變得更為糟糕,因?yàn)槲覀冃枰缘讓拥臉I(yè)務(wù)實(shí)體為輸入從而輸出上層的實(shí)體。當(dāng)你以一個(gè)順序工作流的方式完成一整套操作的時(shí)候,也許感覺很有成就感,整個(gè)過程天衣無縫,完美無缺。但是當(dāng)我們嘗試改變其中的某些內(nèi)容的話,噩夢(mèng)就開始了,實(shí)體的改變勢(shì)必會(huì)引起邏輯的改變,但是這種改變是有連鎖反應(yīng)的。

  業(yè)務(wù)實(shí)現(xiàn)的過程很多時(shí)候就是不同層次間的實(shí)體的轉(zhuǎn)化過程,那么實(shí)現(xiàn)過程中單單考慮解除依賴不能收到很好的效果,從業(yè)務(wù)邏輯的職責(zé)出發(fā),劃分出清晰的業(yè)務(wù)層次,再以實(shí)體轉(zhuǎn)變的結(jié)合點(diǎn)來考慮分解才能達(dá)到良好的效果。

  獨(dú)立的領(lǐng)域?qū)佑葹橹匾?/h4>

  各種經(jīng)典的MVC架構(gòu)的實(shí)現(xiàn),常常讓人產(chǎn)生誤解,認(rèn)為那樣做就已經(jīng)完美了。事實(shí)上,一個(gè)業(yè)務(wù)的框架的重點(diǎn)不是增、刪、改、查,我更傾向于將DAO從業(yè)務(wù)框架中分離出去(最后我也是這樣做的),整個(gè)系統(tǒng)應(yīng)該提供統(tǒng)一的DAO服務(wù),子業(yè)務(wù)框架要專注于業(yè)務(wù)的實(shí)現(xiàn)。

  當(dāng)我們嘗試將一整套業(yè)務(wù)實(shí)體獨(dú)立出來的時(shí)候,我們認(rèn)為已經(jīng)做了很好的業(yè)務(wù)理解,但是這是只見樹木不見森林的想法。在某些系統(tǒng)中,領(lǐng)域的實(shí)現(xiàn)只占代碼總量的很少一個(gè)比例,但是其重要性往往卻是相反的一個(gè)比例。當(dāng)我們選擇將領(lǐng)域代碼和其他代碼混合在一起的時(shí)候,意味著我們的分層結(jié)構(gòu)也隨之混亂。

  "用標(biāo)準(zhǔn)的架構(gòu)模式來完成與上層的松散關(guān)聯(lián)。將所有與領(lǐng)域相關(guān)的代碼都集中在一層,并且將它與用戶界面層、應(yīng)用層和基礎(chǔ)結(jié)構(gòu)層的代碼分離。領(lǐng)域?qū)ο罂梢詫⒅攸c(diǎn)放在表達(dá)領(lǐng)域模型上,不需要關(guān)系它們自己的顯示、存儲(chǔ)和管理應(yīng)用任務(wù)等。這樣使模型發(fā)展得足夠豐富和清晰"。在清楚了整個(gè)領(lǐng)域模型之后,再考慮選擇合適的模式來解決分層問題,我覺得是合理的做法。

  在對(duì)業(yè)務(wù)和領(lǐng)域沒有充分理解的時(shí)候不要下手

  在重構(gòu)過程中,發(fā)現(xiàn)很多業(yè)務(wù)實(shí)體的定義不著邊際,很多概念只是對(duì)數(shù)據(jù)實(shí)體的拓展,結(jié)果出來的東西和數(shù)據(jù)實(shí)體的邏輯關(guān)系截然不同。對(duì)數(shù)據(jù)調(diào)取的邏輯沒有充分理解,那么組織業(yè)務(wù)實(shí)體的時(shí)候很容易出現(xiàn)不恰當(dāng)?shù)臄?shù)據(jù)訪問方式,比如循環(huán)訪問數(shù)據(jù)庫。

  如果整個(gè)領(lǐng)域模型的建立和劃分都是錯(cuò)誤的話,我們?nèi)匀荒軐?shí)現(xiàn)所需要的功能,但是如果對(duì)這樣的代碼進(jìn)行重構(gòu)無疑等于推倒重來。

  現(xiàn)在看來,當(dāng)我們?yōu)榱藢?shí)現(xiàn)功能而急匆匆的不擇手段的時(shí)候,為將來的維護(hù)和升級(jí)埋下了隱患。當(dāng)我們想要將公用的數(shù)據(jù)調(diào)取和業(yè)務(wù)邏輯實(shí)現(xiàn)從各個(gè)子項(xiàng)目中抽象出來變成基類、接口、Helper或者Service的時(shí)候,我發(fā)現(xiàn)不同子項(xiàng)目的開發(fā)者對(duì)業(yè)務(wù)和領(lǐng)域的理解有著很大的差異,因而在實(shí)現(xiàn)方式和實(shí)體定義上都有很大的不同。這個(gè)時(shí)候我們又注意到組織實(shí)體的邏輯并沒有單獨(dú)的分離出來,抽取的工作遇到了難題。也許我們可以分離出代理,然后使用Adapter來適應(yīng)原有的實(shí)體組織邏輯,又或許我們應(yīng)該廢除不合理的實(shí)體定義,也意味著廢除了相應(yīng)的實(shí)現(xiàn)邏輯。

  如果我選擇將不合理的實(shí)體替換為正確的實(shí)體定義將面臨巨大的挑戰(zhàn),也許從數(shù)據(jù)調(diào)取到最終的邏輯都要調(diào)整。當(dāng)然全面調(diào)整的原因是我們沒有實(shí)現(xiàn)很好的隔離。

  迷茫,面對(duì)一個(gè)幾千行的Method

  這是我無法容忍的情況,整個(gè)子業(yè)務(wù)的實(shí)現(xiàn)幾個(gè)大方法全搞定了,每個(gè)方法里無數(shù)個(gè)"Region"和"End Region"。這樣的情況就別談什么分離和設(shè)計(jì)了。最起碼的,當(dāng)你在用"Region"和"End Region"的時(shí)候,就應(yīng)該意識(shí)到這里可以分離出一個(gè)方法來。

  大方法帶來很多弊端。它的可維護(hù)性差,可閱讀性差,和系統(tǒng)的分層結(jié)構(gòu)不融合,不能進(jìn)行有效的單元測試。當(dāng)然對(duì)大方法的重構(gòu)并不像代碼本身那么發(fā)雜,如果它的邏輯足夠清晰的話。但是如果一個(gè)思維足夠清晰的程序員又怎么會(huì)寫出這樣的代碼,所以對(duì)這樣的代碼進(jìn)行重構(gòu),面臨一個(gè)很大的問題就是那些在不同邏輯里重用的局部變量。當(dāng)然更重要的問題是理不清頭緒。

  光去抱怨是沒什么意義的,這樣的方法出現(xiàn)的原因是什么呢?一個(gè)是開發(fā)者沒有很好的理解業(yè)務(wù)框架的結(jié)構(gòu)和目的,二是對(duì)程序設(shè)計(jì)的基本思想理解的不夠好,三是對(duì)業(yè)務(wù)邏輯本身理解的不夠清晰。對(duì)于這樣的實(shí)現(xiàn)去重構(gòu),除了從業(yè)務(wù)角度出發(fā),抽絲剝繭,慢慢的剝離,還有什么好辦法呢?推倒重來嗎?

  重構(gòu),要隨時(shí)進(jìn)行

  當(dāng)有一份代碼覺得不合適,而沒有及時(shí)重構(gòu)的話,那么整個(gè)解決方案就可能變成垃圾場。后續(xù)的開發(fā)人員會(huì)以存在即合理的想法來看待這些垃圾代碼。尤其是新加入的成員,只能模仿別人在怎么做。從測試驅(qū)動(dòng)的開發(fā)理念看,程序開發(fā)是一個(gè)不斷重構(gòu)的迭代過程。很多人將重構(gòu)看成是一件大事,一聽到重構(gòu)就害怕起來,尤其是測試團(tuán)隊(duì)。當(dāng)然這里不能否認(rèn),不恰當(dāng)?shù)闹貥?gòu)會(huì)給測試團(tuán)隊(duì)造成很大的麻煩。

  集中重構(gòu)是極其錯(cuò)誤的思想。不要想著等某些開發(fā)任務(wù)結(jié)束了,有時(shí)間了再集中精力來重構(gòu)代碼。當(dāng)系統(tǒng)相對(duì)穩(wěn)定之后,重構(gòu)要付出的代價(jià)可能是整個(gè)團(tuán)隊(duì)無法接受的。對(duì)分層架構(gòu)的重構(gòu)應(yīng)該是建立架構(gòu)的最初一段時(shí)間,不斷的調(diào)整達(dá)到最優(yōu)。當(dāng)項(xiàng)目進(jìn)行一段之后,再來調(diào)整整體結(jié)構(gòu)無疑是讓人無法接受的。

  重構(gòu)要避免過度設(shè)計(jì)

  最后要說的是,重構(gòu)要圍繞一個(gè)適度的目標(biāo)來進(jìn)行,要考慮代價(jià),同時(shí)不代表模式應(yīng)用的越多越好。相反的,在重構(gòu)過程中,要時(shí)時(shí)考慮是否把簡答的事情想復(fù)雜了。

  目前我重構(gòu)的代碼中,還沒有這樣的問題,這里也就不啰嗦了。

  說了這么多,我還是想聽聽各位的看法和感受,如何進(jìn)行有效的重構(gòu),如何在編程的最開始的階段就避免很多重構(gòu)障礙的產(chǎn)生?

it知識(shí)庫重構(gòu),讓人快樂讓人苦,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 赤城县| 抚州市| 德阳市| 随州市| 尚义县| 克拉玛依市| 天镇县| 蒲城县| 延津县| 灵石县| 松阳县| 宜章县| 鄂州市| 丹棱县| 台南县| 时尚| 晋州市| 炎陵县| 凯里市| 儋州市| 南投县| 习水县| 芦山县| 柳州市| 郑州市| 宜昌市| 土默特右旗| 泗阳县| 临洮县| 淄博市| 临夏市| 喀喇| 滦南县| 蕉岭县| 怀柔区| 姜堰市| 永仁县| 赞皇县| 高邮市| 九龙县| 鹤山市|