黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

大話重構(gòu)連載19:大對象的演化過程

系統(tǒng) 2296 0
很好,我們終于邁出了重構(gòu)的第一步,而這第一步我們瞄準了代碼問題的重災區(qū)——超級大函數(shù)。超級大函數(shù)之所以是代碼問題的重災區(qū),就是因為它們往往難于閱讀、難于維護。面對大函數(shù)我們采取的辦法是拆分,以功能為核心將其拆分成一個一個獨立的函數(shù)。拆分后的程序變得易于閱讀了,因為要讀懂程序你不再需要讀完所有代碼,選擇性的讀取那些頂級函數(shù),只需了了數(shù)行代碼,你就可以明白整個程序。

但是,當我們將數(shù)千行的大函數(shù)分解成數(shù)十個小函數(shù)時,另一個問題出現(xiàn)了。想象一下,數(shù)十個函數(shù)被雜亂無章地堆放在一個對象中,看看就讓人頭疼。實際上,我們是不會這樣做的。當我們開始了對大函數(shù)的分解時,隨之而來的就是對大對象的分解。大對象,就是指的那些包含數(shù)十個甚至上百個方法或者函數(shù),功能無所不包的超級對象。在很多遺留系統(tǒng)中,總有那么幾個超級對象,系統(tǒng)幾乎所有的功能都在它的里面有對應方法。這樣的對象,密密麻麻的方法讓人困惑,更關鍵的是,各種各樣的功能被耦合在一起,稍有修改就會影響到許多功能,甚至讓那些毫不相干的功能產(chǎn)生BUG。因此,我們應當合理地拆分我們的大對象。

與大函數(shù)一樣,很多時候遺留系統(tǒng)中的大對象,也都是伴隨系統(tǒng)業(yè)務復雜度的逐漸增長而出現(xiàn)的,我們來看看它的演進過程吧。我們說軟件實際上是對現(xiàn)實世界的模擬,通過這種模擬,實現(xiàn)信息化的管理,來提高我們的生產(chǎn)效率。但是,現(xiàn)實世界是復雜的,各種事物之間存在著各種各樣紛繁復雜的聯(lián)系,因此我們不可能完全模擬現(xiàn)實世界的所有,只可能是現(xiàn)實世界的一部分,客戶急需要模擬的那一部分。

人的大腦認識事物總是一個由簡單到復雜的過程,這是我們的客觀規(guī)律。因此,我們的軟件模擬真實世界也是一個由簡單到復雜的過程。最開初我們的想法總是非常簡單而單純的,就是讓軟件做一件非常簡單而明確的事情。由于這時候業(yè)務非常簡單,我們不需要太多的類和方法就可以實現(xiàn)業(yè)務操作。比如開票業(yè)務,就是將已開具的發(fā)票信息讀取出來,保存。這樣一個簡單操作,設計成一個簡單的開票業(yè)務類合情合理。

但是,隨著軟件模擬真實世界的不斷發(fā)展,業(yè)務變得越來越復雜。比如這個開票業(yè)務,我們隨后的業(yè)務開始變更,要檢查購方是否存在、開票人是否有權(quán)限、庫存中是否還有發(fā)票,等等。起初只有一種開票方式,但隨著非正常開票業(yè)務的增加,許多相關的業(yè)務也隨之變化……隨著業(yè)務的不斷增加,軟件代碼的規(guī)模也在發(fā)生著質(zhì)的變化(如圖6.1所示)。



圖6.1 開票業(yè)務的演化過程


過去開票業(yè)務類只有百來行代碼,現(xiàn)在被膨脹到數(shù)千行代碼。各種條件語句層層嵌套,各種臨時變量穿插跑位,程序變得難于理解。由于讀不懂代碼,修改代碼的程序員開始在走鋼絲,一不小心改動了某個關鍵程序就可能引入重大BUG。為了避免重大BUG的出現(xiàn),測試人員耗費巨大精力進行嚴格的測試。毫無疑問,軟件開始進入一種惡性循環(huán),軟件退化開始一步步加深。

面對這種軟件規(guī)模增大而帶來的惡性循環(huán),我們必須做出改變。面對問題我們不能病急亂投醫(yī),而是應當對癥下藥。這個正確的藥方就是以職責驅(qū)動設計思想為核心,調(diào)整我們的程序結(jié)構(gòu),構(gòu)建高內(nèi)聚、低耦合的軟件系統(tǒng)。職責驅(qū)動設計,就是要求我們設計的所有類和接口,都要有自己的職責定義。而每個類和接口內(nèi)部的所有方法和屬性都是圍繞著該職責來進行的,它們都是高度相關的。每個類和接口決不去做跟自己職責無關的事情,所有與自己職責無關的事情,都應當交給其它擁有該職責的類來完成,而自己僅僅是去調(diào)用。這就是職責驅(qū)動設計的思想,而每個類其內(nèi)部包含的功能所達到的高度相關的程度,我們稱之為“內(nèi)聚”。

概念似乎有一些抽象,我們來舉例說明吧。對于開票業(yè)務,我們設計了開票業(yè)務類來處理它,因此開票業(yè)務類的職責就是完成開票操作,這似乎毫無問題。但是,我們仔細審視開票操作,就會發(fā)現(xiàn)它包含了好幾個部分:首先,我們讀取客戶、開票人、發(fā)票庫存等信息進行相關的校驗,然后保存這些發(fā)票到數(shù)據(jù)庫中,最后統(tǒng)計當月的票量及金額。通過這樣的分析,它們似乎不再那么功能相關了,讀取和校驗客戶、開票人、發(fā)票庫存等信息是客戶、開票人、發(fā)票庫存實體類的職責,讀取和保存發(fā)票似乎是發(fā)票類的職責,而統(tǒng)計當月票量與金額似乎是財會統(tǒng)計類的職責。分與不分,完全取決于軟件代碼的復雜程度。如果總共也就幾十行代碼,我們寫成一個類中的幾個方法就可以了;但隨著功能復雜度的加深,那么我們必須得拆分,分配到不同的類中配合完成我們的功能。

隨著軟件業(yè)務的不斷變化,我們的軟件在發(fā)生著質(zhì)的變化。發(fā)票保存前我們必須要進行一系列的校驗工作:檢查購方是否存在、開票人是否有權(quán)限、是否還有發(fā)票庫存,等等。不同的校驗,讀取的是不同的數(shù)據(jù),它們的順序可能變化,校驗的個數(shù)也可能在調(diào)整。隨著需求的變化,一些校驗被增加進來而另一些則被剔除。我們判斷功能是否相關的一個非常重要的原則,就是是否是軟件變更的同一個原因。比如,“檢查購方是否存在”與“開票人是否有權(quán)限”,不是軟件變更的同一個原因:“檢查購方是否存在”是與客戶信息管理直接相關,而“開票人是否有權(quán)限”則是與用戶權(quán)限定義密切相關,因此它們不能放在同一個類中。為什么呢?因為“檢查購方是否存在”的業(yè)務邏輯變更時,不應當影響到“檢查開票人是否有權(quán)限”的功能。最好的辦法就是,將它們各自封裝在各種相關的業(yè)務類中(如圖6.2所示)。



圖6.2 開票業(yè)務的拆分


經(jīng)過以上分析我們發(fā)現(xiàn),開票操作隨著業(yè)務邏輯的不斷發(fā)展,應當在原有的程序結(jié)構(gòu)上,將開票業(yè)務類拆分成幾個部分:各種校驗類、發(fā)票業(yè)務類與財會統(tǒng)計類。這樣的拆分使得開票業(yè)務類最終由一個什么都干的多面手,變成了一個管理者。它不再參與那些具體的工作,而是將工作分配給不同的人,成為一個組織協(xié)調(diào)者。經(jīng)過這樣的調(diào)整,我們的程序?qū)⒆兊酶右子陂喿x、維護、變更。

大話重構(gòu)連載首頁: http://fangang.iteye.com/blog/2081995
特別說明:希望網(wǎng)友們在轉(zhuǎn)載本文時,應當注明作者或出處,以示對作者的尊重,謝謝!

大話重構(gòu)連載19:大對象的演化過程


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發(fā)表我的評論
最新評論 總共0條評論