自“重構(gòu)”一詞被Martin Fowler在上世紀末提出以來,一直受到諸多軟件開發(fā)人員的追捧,圈內(nèi)人若是對重構(gòu)不大關注,似乎是有些數(shù)典忘祖的意味。于是乎,圈內(nèi)人無論自身水平如何都開始關注重構(gòu),開始動手“去做”;至于做得好不好,結(jié)果合理與否,很難有事實標準去衡量。
越來越多的“網(wǎng)紅重構(gòu)”
Martin Fowler在寫《重構(gòu)》一書時,明確提出了重構(gòu)的幾個目的:
- 改進設計
- 使得軟件更易被人理解
- Find Bugs
- 提高開發(fā)速度
可見重構(gòu)的起點很明確--改進設計,OOP的出現(xiàn)為“軟件設計“賦予了更深層的定義:”高內(nèi)聚、低耦合“無人不知,無人不曉,可以被用于很多領域的設計工作上;然而對SOLID理解透徹的軟件從業(yè)人員又有幾何?
重構(gòu)不是一時沖動,也不是為了達成特定的業(yè)績目標。我更希望它能夠成為軟件從業(yè)人員自身的基本素質(zhì),不必時時刻刻掛在嘴邊。重構(gòu)的特殊性使得其價值體現(xiàn)有很長的延遲,只有出于本能的重構(gòu)才是純潔的,如果帶有任何利益相關的目的性,那么這個重構(gòu)就是有污點的。
如何改進設計?
業(yè)務是根本。不論是多復雜的軟件,其根本目的都是為了實現(xiàn)人的業(yè)務需求,因此軟件世界與真實世界有很多的相似性。關鍵過程就在于,我們?nèi)绾伟讶说男枨蠓g成軟件模型呢?
UML的出現(xiàn)為軟件設計領域提供了事實標準,我們開始了解到了參與軟件系統(tǒng)的一些關鍵角色;以及這些角色的依賴關系,甚至開始關注這些角色的狀態(tài)變更。于是我們發(fā)現(xiàn)“抽象”極其重要,對于一個經(jīng)常變化的業(yè)務需求,我們需要關注這些要點:
- 基本流程和處理步驟是什么?
- 有哪些關鍵角色參與了這個流程?
- 這些角色自身有什么特點(屬性)?
- 這些角色是如何協(xié)同、合作(依賴、組合...關系)的呢?
- 角色是否會發(fā)生狀態(tài)變化(狀態(tài)圖)?
弄清楚了以上的內(nèi)容,就可以按照UML標準給出一系列的設計圖,用于說明你的設計意圖(此處不建議其他的表達形式,鑒于UML已經(jīng)足夠成熟和被認可),但這個設計意圖并不一定是最優(yōu)解。
抽象與模式
OOP的魅力就在于抽象與復用,抽象其本質(zhì)是分離穩(wěn)定不變的點,而復用則是為了應付軟件系統(tǒng)的復雜性,提供足夠的靈活性來擴展軟件系統(tǒng)。任何軟件系統(tǒng)與真實世界必然存在聯(lián)系,我們不妨先脫離軟件設計本身的理論,僅考慮真實世界的類似場景,看看這個場景中存在哪些不變的參與者。
例如,我們在超市購物時,通常會有這樣的場景:找到一輛購物車->選購商品->往收銀臺結(jié)算->付款打印小票。對應的,如果將這套業(yè)務搬到軟件系統(tǒng)中,我們就會發(fā)現(xiàn)一些穩(wěn)定出現(xiàn)的參與者:顧客(Customer),購物車(ShoppingCart),商品(Product),訂單(Order),交易(Transaction),小票(Receipt)。
再深入探究一下這些參與者的行為特征:顧客通常會找購物車,會瀏覽商品信息選擇是否購買,結(jié)賬時支付訂單;購物車就比較單純,只負責裝添加的貨物;商品能夠展示價格和基本信息;顧客推購物車去結(jié)算的時候會產(chǎn)生訂單,結(jié)算時就完成了一筆或多筆交易,交易完成以后顧客就拿到了小票。把這些參與者的行為特征(業(yè)務方法)和自身屬性組合起來,我們就有了軟件系統(tǒng)中對應的一個角色,通常我們把它稱之為“領域?qū)ο蟆保―omain Object)。
完成抽象之后,進一步關注這些領域?qū)ο笾g的協(xié)同合作關系,此時我們就可以用上GOF的幾十種設計模式(足夠應付大多數(shù)場景)了。
更為一般的設計方法
并不是所有的場景都能非常明確地表明有多少參與者,這通常由業(yè)務需求在初期不明確且實現(xiàn)時缺少設計導致的,且大多數(shù)重構(gòu)都是在這種場景下開展的。
IPO,即Input-Process-Output,對應于軟件系統(tǒng)中的輸入、處理和輸出。對于已經(jīng)識別的重構(gòu)場景,不妨先關注這三個點:
- 輸入,這些輸入有什么共同特點,是怎么被構(gòu)建的呢?
- 處理,對輸入做了什么處理呢?產(chǎn)生了多少個中間角色?一共有多少角色參與?這些角色又是怎么聯(lián)系起來的呢?
- 輸出,處理完成之后,軟件系統(tǒng)輸出了什么?系統(tǒng)其它模塊對這個輸出如何使用?
關注輸入,可以提取到軟件系統(tǒng)中關鍵的數(shù)據(jù)模型,針對其構(gòu)建特點通常可以引入“構(gòu)建型設計模式”;
關注處理和輸出,可以更清晰地找到關鍵的參與角色,引入合理的“結(jié)構(gòu)型模式”來規(guī)范這些角色之間的交互方式;如果能把這些角色的行為再進行組織和分析,通?!靶袨樾湍J健本涂梢员灰肓?。
什么是重構(gòu)?
《重構(gòu)》一書的推出,使得我們越來越關注所謂的代碼壞味道,出現(xiàn)這些壞味道的根本原因就在于軟件系統(tǒng)的抽象與設計不合理。如果只是識別了這些壞味道,把書中的手段一一應用,似乎很難讓人信服這是一次完整的重構(gòu)。所謂的“網(wǎng)紅重構(gòu)”,大抵如此吧。
總之,任何不關注改善設計和解讀設計意圖的重構(gòu)都是雞肋。
注:
- UML:Unified Modeling Language,一種開放的方法,用于說明、可視化、構(gòu)建和編寫一個正在開發(fā)的、面向?qū)ο蟮?、軟件密集系統(tǒng)的制品的開放方法。UML展現(xiàn)了一系列最佳工程實踐,這些最佳實踐在對大規(guī)模,復雜系統(tǒng)進行建模方面,特別是在軟件架構(gòu)層次已經(jīng)被驗證有效。
- 領域?qū)ο螅侯I域驅(qū)動設計的關鍵術語
- GOF設計模式:Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides合著的《Design Patterns: Elements of Reusable Object-Oriented Software》