大話重構連載5:軟體修改的四種動機

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   使用   

軟體,自從被我們開發出來並交付使用以後,如果它運行得好好的,我們是不會去修改它的。我們要修改軟體,萬變不離其宗,無非就是四種動機:

1.增加新功能;

2.原有功能有BUG;

3.改善原有程式的結構;

4.最佳化原有系統的效能[1]。

第一種和第二種動機,都是源於客戶的功能需求,而第四種是源於客戶的非功能需求。

軟體的外部品質,其衡量的標準就是客戶對軟體功能需求與非功能需求的滿意度。它涉及到一個企業、一個軟體的信譽度與生命力,因此為所有軟體企業所高度重視。但是,就在所有企業高管把軟體外部品質放在高於一切的高度的同時,軟體內部品質卻長期為人所漠視。企業沒有保證軟體內部品質的措施,甚至因為需要趕工而肆意地降低內部品質的標準。這樣帶來的長期惡果就是,程式編寫越來越爛,運行效率越來越低,程式結構越來越讓人看不懂。當一群群剛剛畢業的大學生遊走在這堆寫得很爛的代碼中時,他們開始沉淪,開始天真地以為代碼就是這樣寫的(真是毀人不倦呀)。當我們的軟體企業培養出一批批品質不高的開發人員,開發出一個個品質低下的軟體系統時,它們開始發現軟體維護成本越來越高,最終不得不收穫自己種下的惡果。

要提高軟體內部品質,毫無疑問就是軟體修改的第三個動機:改善原有程式的結構。它的價值是隱性的,並不體現在某一次或兩次開發中,而是逐漸體現在日後長期維護的軟體過程中。高品質的軟體,可以保證開發人員(即使是新手)能夠輕易看懂軟體代碼,能夠保證日後的每一次軟體維護都可以輕易地完成(不論軟體經曆了多少次變更,維護了多少年),能夠保證日後的每一次需求變更都能夠輕易地進行(而不是傷筋動骨地大動)。要做到這幾點其實並不容易,它需要我們持續不斷地對系統內部品質進行最佳化與改進。這,就是系統重構的價值。

為了有效提高軟體的內部品質,我們在系統重構中應當做哪些事情呢?首先是提高軟體的可讀性、易於閱讀。軟體要可讀,並不是添加幾行注釋那麼簡單的事兒,首先是軟體的商務邏輯要清晰。一個商務程序可能其處理過程可能非常複雜,如果在一個函數中順序地一行一行寫下來,可能需要寫數百行,甚至上千行。比如,我們要實現這樣一個需求:像Spring那樣從一個或者數個設定檔中讀取XML,然後根據XML依次去建立每一個bean,將每一個bean放到beanFactory中。如果沒有經過精心地設計,而是隨性地一行一行寫,要實現這個功能沒個幾百上千行代碼,想想都難。但如果我們換個思路,在入口函數裡僅僅調用幾個頂級方法,比如findXmlFile()、readXmlStream()、buildFactory(),然後依次去實現這幾個頂級方法,程式結構就會變得清晰而易讀。請看這段範例程式碼:

 1 public abstract class XmlBuildFactoryTemplate { 2     /** 3      * 初始化工廠。根據路徑讀取XML檔案,將XML檔案中的資料裝載到工廠中 4      * @param path XML檔案的路徑 5      */ 6     public void initFactory(String path){ 7         //尋找XML檔案,讀取資料流 8         InputStream inputStream = findXmlFile(path); 9         //解析XML檔案,返回根10         Element root = readXmlStream(inputStream);11         //根據XML檔案建立類,放入工廠中12          buildFactory(root);13     }14     /**15      * 讀取一個XML的檔案,輸出其資料流16      * @param path XML檔案的路徑17      * @return InputStream檔案輸入資料流18      */19     protected InputStream findXmlFile(Stringpath) {20         ......21     }22     /**23      * 讀取並解析一個XML的檔案輸入資料流,以Element的形式擷取XML的根,返回之24      * @param inputStream 檔案輸入資料流25      * @return ElementXML的根26      */27     protected Element readXmlStream (InputStream inputStream) {28         ......29     }30     /**31      * 用從一個XML的檔案中讀取的資料構建工廠32      * @param root 從一個XML的檔案中讀取的資料的根33      */34     protected abstract void buildFactory(Element root);35 }

在實現這幾個頂級函數的時候,我們還會將一些比較獨立的功能分解出去,形成類與介面,比如這裡的findXmlFile(),它可能會以各種方式去尋找XML檔案,這時把這些功能提取出來,形成Resource介面和它的多個實現(1.1所示),為findXmlFile()所調用。如果我們將這個複雜的功能設計成這樣,則毫無疑問,系統可讀性將大大提高。

圖1.1 工廠類模板的設計圖

此外,在物件導向的世界裡,我們設計的類、方法、關聯,應當與現實世界中的事物、行為,及其相互的關係對應起來。現實世界有什麼事物,這些事物都應當有什麼行為,相互之間是什麼關係,則我們在軟體世界裡就應當設計什麼類、什麼方法和它們之間的關聯關係。只有這樣的設計才是最易於為人所理解的設計,這就是“領域驅動設計”的思想[1]。在系統重構中,我們將使用“抽取方法”來分解難於閱讀與維護的大函數,用“抽取對象”來分解無所不能的大對象。

系統重構要乾的另一件事情就是使軟體易於維護、易於變更。軟體需求總是變得越來越複雜,這是無法改變的客觀事實。在添加新功能的同時,我們既要保證原有代碼的有效性,又必須有效地複用原有的代碼。這是多麼矛盾的一件事兒啊!怎麼辦呢?看我在後面一步一步給你分解……


[1] 領域驅動設計(DDD: Domain-DrivenDesign),源自軟體理論大師Eric Evans在其2010年發表的同名著作中提出來的設計思想,本文將大量提及。


大話重構連載首頁:http://www.cnblogs.com/mooodo/p/talkAboutRefactoringHome.html

特別說明:希望網友們在轉載本文時,應當註明作者或出處,以示對作者的尊重,謝謝!


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.