- 工信部備案號 滇ICP備05000110號-1
- 滇公安備案 滇53010302000111
- 增值電信業務經營許可證 B1.B2-20181647、滇B1.B2-20190004
- 云南互聯網協會理事單位
- 安全聯盟認證網站身份V標記
- 域名注冊服務機構許可:滇D3-20230001
- 代理域名注冊服務機構:新網數碼
復用是架構思維中非常重要的思維之一,是面向對象架構設計的核心思想,業務能力組件化,組件能力服務化,共享平臺,中臺建設,公共服務下沉等都是為了提高系統的復用而設計。
好的系統設計具備可擴展性(Extensibility)、靈活性(Flexibility)和可插入性(Pluggability),一個復用較好的系統,就是一個易維護的系統。但實際上,可維護性和可復用性是兩個緯度。
一、可維護性
可維護性指系統的被修改能力和可修復能力,修改能力指改進、系統環境、需求、系統容量等變化的適應;可修復能力指系統發生故障后,能夠排除(或抑制)故障予以修復,并能按照原有設計流程正常運行狀態的可能性。可維護性架構有如下特征:
(1)易分析性
系統發生故障或缺陷時,能很快定位或分析出原因。
(2)易改變性
面對新需求系統擁有快速被實現的能力,實現體現在代碼實現、設計實現和說明文檔的更新。
(3)易測試性
系統新的變更可以被驗證的能力。
(4)穩定性
兼容新的變更不影響原有系統的運行的能力。
(5)依從性
架構設計遵循和保持相關約定的能力。
對于系統可維護性的度量可以從以下幾個方面進行判斷:
a.可理解性。指通過分析源碼和解讀相關設計文檔來了解系統架構、功能和運行邏輯的難易程度。一個可理解性高的系統一般應具備以下的特征:模塊化(系統各個模塊結構良好、功能完整),程序代碼清晰,編程風格具有一致性(代碼風格及設計風格的一致性),完整性(對輸人數據進行完整性檢查),使用有意義的數據名和函數名等。
b.可靠性。可靠性表明一個系統在給定的一段時間內正確執行的概率。衡量可靠性的方法主要有兩類:第一類是根據程序錯誤的統計數字來進行可靠性預測。比如用一些可靠性模型,根據程序測試中發現并排除的錯誤數來預測平均失效間隔時間(Mean Time To Failure,MTTF)。第二類是當系統的可靠性與復雜性有關時,可以根據程序的復雜性來預測軟件的可靠性。
c.可測試性。可測試性表明能夠用測試的方法來驗證程序正確性的難易程度。系統的可測試性取決于系統的可理解性、復雜性、設計合理的測試用例的難易程度等方面的內容。
d.可修改性。可修改性描述了程序能夠被正確修改的難易程度。一個可修改的程序應當是可理解的、通用的、簡單的、靈活的。通用性是指程序適用于各種功能變化而無需修改。靈活性是指能夠容易地對程序進行修改。
e.可移植性。可移植性表明程序從一個運行環境移植到另一個新的運行環境的可能性的大小。一個可移植性好的系統應具有結構良好、靈活、不依賴于某一具體計算機或操作系統的特性。
系統的可維護性不但和架構師采用的分析設計方法和技術熟練程度有關,還和項目管理技術有密切的聯系,除了和設計開發方法有關的因素之外,還有一些因素影響系統的可維護性的原因:
f.開發人員是否有統一的約束規范
g.從需求——業務分析——架構設計——編碼實現——測試發布——線上運營是否采用了統一的文檔結構和文檔形成機制。
h.是否應用了可維護性的語音和框架
i.是否有完整的代碼說明文檔
j.是否有持續更新保存規范化的測試用例信息
二、可復用性
復用性是面向對象技術最重要的特征之一,但是事與愿違復用性的好處,我們在架構設計時并不能真正實現,因為復用需要付出一定的代價,并不像我們使用面向對象開發工具一樣,很容易利用起復用性特性完成相關工作。相反,為了打到系統的復用性,我們需要取舍一些設計。另外好多設計者對于復用的范圍很有局限,常常會考慮代碼的復用而忽略了其他更高層次的復用,當然代碼的復用是最基本的,代碼的復用有自身的好處,但是為了讓我們的系統復用,希望設計者能從更高的層次來看待復用。
1。復用性的好處
有較高的生產效率。
有較高的系統質量。
恰當運用復用可以改善系統的可維護性。
2。復用分類
我們可以將系統復用分為代碼復用、算法的復用、數據結構的復用、測試信息的復用、設計的復用、分析的復用,接下來我們就詳細講解如何做這些復用。
(1)代碼復用
代碼復用是最常見的復用,包括目標代碼和源代碼的復用,指的是在同一個應用的多個模塊中,或者是在多個應用下代碼的復用。理想狀況下,代碼復用可以共享通用類、函數集合來實現;即便是在最差的情況下,代碼復用也可以通過拷貝和修改源代碼來實現。
代碼復用的一個關鍵因素是你要能夠獲取到代碼。如果必要的話,你自己可以修改這段代碼,當然也可以找別人幫你修改。這一點好壞并存,通過審讀代碼,你可以自己決定—— 哪怕這個決定很難做出—— 你是否要復用這段代碼。同時,把代碼開放給你,那么代碼原作者也許會失去撰寫說明文檔的動力,這也就增加了你理解它所花費的時間,減小了你可能獲得的收益。
代碼復用的最大好處在于它可以減少你的代碼量,也就潛在地減小了開放和維護成本。壞處則在于你自己應用的能力范圍就被約束住了,而且也增加了應用和被復用代碼之間的耦合。要大規模地實現源程序的復用,只有依靠含有大量可復用構件的構件庫,如“對象鏈接與嵌入”技術,既支持在源程序級上定義構件以構造新的系統,又使這些構件在目標代碼級上仍然是一些獨立的可復用構件,能夠在運行時被靈活地重新組合為各種應用系統。
代碼復用是最基礎最基本的復用,那我們就來看看做到代碼復用應該注意哪些內容:
a.面向接口編程
"面向接口編程"是面向對象設計(OOD)的第一個基本原則。面向接口編程就是先把客戶的業務邏輯線提取出來,作為接口,業務具體實現通過該接口的實現類來完成。當客戶需求變化時,只需編寫該業務邏輯的新的實現類,通過更改配置文件(例如Spring框架)中該接口的實現類就可以完成需求,不需要改寫現有代碼,減少對系統的影響。
b.使用對象組合而不是繼承
"優先使用組合而不是繼承"是面向對象設計(OOD)的第二個基本原則。繼承是在程序開發的過程中重構得到的,而不是程序設計之初就使用繼承,很多開發者濫用繼承,結果可能造成后期的代碼解決不了需求的變化。因此,優先使用組合而不是繼承,是面向對象開發的一個重要經驗。
繼承:繼承的起源,來自于多個類中相同特征和行為的抽象。子類可以通過繼承父類,那么可以調用父類中定義的方法和屬性,從而達到代碼重用的目的。另外,子類除了重用父類的代碼以外,還可以擴展自身的屬性和方法,來描述子類特有的特征和行為。
對象組合:對象組合要求被組合的對象具有良好的接口,并且通過從其他對象得到的引用在運行時運態定義。對象組合是類繼承之外的另一種復用選擇,可以將對象組合到其他對象中,以構建更加復雜的功能。由于對象的內部細節對其他對象不可見,它們看上去為“黑箱”,這種類型的復用稱為黑箱復用(black-box reuse)。對象只以"黑箱"的形式出現。
下面分析繼承和組合的優缺點:
(a)繼承的優缺點
優點:
繼承簡單粗爆,直觀,關系在編譯時靜態定義。
被復用的實現易于修改,sub可以覆蓋super的實現。
缺點:
無法在運行時變更從super繼承來的實現(也不一定是缺點)
sub的部分實現通常定義在super中。
sub直接面對super的實現細節,因此破壞了封裝。
super實現的任何變更都會強制子類也進行變更,因為它們的實現聯系在了一起。
如果在新的問題場景下繼承來的實現已過時或不適用,所以必須重寫super或繼承來的實現。
由于在類繼承中,實現的依存關系,對子類進行復用可能會有問題。有一個解決辦法是,只從協議或抽象基類繼承(子類型化),國為它們只對很少的實現,而協議則沒有實現。
(b)組合的優缺點優點:
不會破壞封裝,因為只通過接口來訪問對象;
減少實現的依存關系,因為實面是通過接口來定義的;
可以在運行時將任意對象替換為其他同類型的對象;
可以保持類的封裝以專注于單一任務;
類和他的層次結構能保持簡潔,不至于過度膨脹而無法管理;
缺點:
涉及對象多;
系統的行為將依賴于不同對象間的關系,而不是定義于單個類中;
現成的組件總是不太夠用,從而導致我們要不停的定義新對象。
c.將可變的部分和不可變的部分分離
"將可變的部分和不可變的部分分離"是面向對象設計(OOD)的第三個基本原則。如果使用繼承的復用技術,我們可以在抽象基類中定義好不可變的部分,而由其子類去具體實現可變的部分,不可變的部分不需要重復定義,而且便于維護。如果使用對象組合的復用技術,我們可以定義好不可變的部分,而可變的部分可以由不同的組件實現,根據需要,在運行時動態配置。這樣,我們就有更多的時間關注可變的部分。對于對象組合技術而言,每個組件只完成相對較小的功能,相互之間耦合比較松散,復用率較高,通過組合,就能獲得新的功能。
d.控制方法的長度
通常,我們的方法應該只有盡量少的幾行,太長的方法會難以理解,而且,如果方法太長,則應該重新設計。對此,可以總結為以下原則:
三十秒原則:如果另一個程序員無法在三十秒之內了解你的函數做了什么(What),如何做(How)以及為什么要這樣做(Why),那就說明你的代碼是難以維護的,必須得到提高;
一屏原則:如果一個函數的代碼長度超過一個屏幕,那么或許這個函數太長了,應該拆分成更小的子函數;一行代碼盡量簡短,并且保證一行代碼只做一件事。
e.消除case / if語句
要盡量避免在代碼中出現判斷語句,使用過多的switch/case 或者 if else 語句,代碼的可讀性很差同時也違背了面向對象的原則。
f.減少參數個數
有大量參數需要傳遞的方法,通常很難閱讀。我們可以將所有參數封裝到一個對象中來完成對象的傳遞,這也有利于錯誤跟蹤。太多層的對象包裝對系統效率有影響,但是它帶來的好處相比,我們寧愿做包裝。畢竟"封裝"也是OO的基本特性之一,而且,"每個對象完成盡量少(而且簡單)的功能",也是OO的一個基本原則。
g.類層次的最高層應該是抽象類。
在許多情況下,提供一個抽象基類有利做特性化擴展。由于在抽象基類中,大部分的功能和行為已經定義好,使我們更容易理解接口設計者的意圖是什么。由于JAVA不允許"多繼承",從一個抽象基類繼承,就無法再從其它基類繼承了。所以,提供一個抽象接口(interface)是個好主意,一個類可以實現多個接口,從而模擬實現了"多繼承",為類的設計提供了更大的靈活性。
h.盡量減少對變量的直接訪問
對數據的封裝原則應該規范化,不要把一個類的屬性暴露給其它類,而是應該通過訪問方法去保護他們,這有利于避免產生波紋效應。如果某個屬性的名字改變,你只需要修改它的訪問方法,而不是修改所有相關的代碼。
i.子類應該特性化,完成特殊功能
如果一個子類只是使一個組件變成組件管理器,而不是實現接口功能,或者,重載某個功能,那么,就應該使用一個外部的容器類,而不是創建一個子類
j.拆分過大的類
如果一個類有太多的方法(超過50個),那么它可能要做的工作太多,我們應該試著將它的功能拆分到不同的類中。
k.作用截然不同的對象應該拆分
對同樣的數據,有不同的視圖。某些屬性描述的是數據結構怎樣生成,而某些屬性描述的是數據結構本身。最好將這兩個視圖拆分到不同的類中,從類名上就可以區分出不同視圖的作用。類的域、方法也應該有同樣的考慮!
為了提高代碼的復用性,還有好多的手段,以上都是多年的編碼經驗,希望能幫助大家。
(2)算法的復用
各種算法如排序算法都已經得到了大量的研究,幾乎不需要我們重寫自己的算法,各種語言通常也實現了這些常用算法,因此直接復用即可。
(3)數據結構的復用
與算法一樣,類似數組、隊列、棧、列表等得到了透徹的研究,只需要直接復用。
(4)測試信息的復用
測試信息的復用主要包括測試用例的復用和測試過程的復用。前者是把一個軟件的測試用例應用于新的軟件測試中,或者在軟件作出修改時使用在新一輪的測試中。后者是在測試過程中通過軟件工具自動記錄測試的過程信息,包括測試員的每一個操作、輸人參數、測試用例及運行環境等信息,并將這些過程信息應用于新的軟件測試或新一輪的軟件測試中。測試信息的復用級別不易同分析、設計、編程的復用級別進行準確地比較,因為被復用的不是同一事物的不同抽象層次,而是另一種信息,但從這些信息的形態來看,大體處于與程序代碼相當的級別。
a.測試用例設計方法
測試用例設計可以分為白盒測試用例設計法和黑盒測試用i設計法。
白盒測試用設計法
黑盒測試用例設計法
(5)設計復用
設計復用指的是使用對以前創建的設計用例、標準文檔、領域模型、過程指導和其它,來幫助你開始一個新工程。設計復用分為幾個層次,從完整的拿來即用這種100%的完全復用,到僅以工件作模型之用,研究分析之以獲取靈感。舉例來說,編碼和用戶界面設計的標準文檔對不同的項目來說,就是有價值的設計,像其中的建模符號定義和方法論總覽這種文檔,是可以直接復用的。我曾經為已有的通用數據接口以面向對象的方式做了包裝,讓這些類使用起來更直觀。
設計復用提升了項目間的一致性,減少了各個項目的管理成本。用戶界面標準對絕大多數平臺來說都是很常用的;編碼標準對主要語言來說都是不可或缺的;而標準面向對象方法論和模型記號這樣的東西已經使用好多年了。主要的壞處在于很多核心程序員總覺得這種復用過了頭,給彼此帶來了強加的標準和過程約束。因此設計復用的底線就是當你覺得它是一種重要、可行和醒目的技術時,再去使用它。這種復用有如下三種途徑。
從現有系統的設計結果中提取一些可復用的設計組件,并將這些組件應用于新系統的設計中。
將一個現有系統的全部設計文檔在新的系統上重新實現,也就是將一個設計運用于多個具體的實現中。
和任何應用無關,獨立設計開發可復用的設計組件。
(6)分析復用
分析復用是比設計復用更高級別的復用,可復用的分析組件是針對業務領域中某些設計或問題抽象出的組件,受設計技術及實現條件的影響很少,所以可復用的機會更大,如領域模型已經顯出巨大的可復用潛能,因為它們反映出大規模的業務行為內聚的特征,在許多應用中都是一致的。你在領域開發中創造的每樣東西都是可以復用的。與后期的復用相比,領域組件在前期業務行為和組織的架構設計中顯出更大的作用。復用的途徑也有三種。
從已有系統的分析結果中提取可復用的組件用于新系統的架構設計。
用一份完整的分析文檔作為輸入,產生針對不同系統和其他實現條件的多項設計。
和任何應用無關,獨立設計開發可復用的分析組件。
三、可復用和可維護性的關系
可復用和可維護性的關系如下。
1.適當地應用復用,同時提高了可維護性,就是在保持甚至提高系統的可維護性的同時,實現系統復用。
2.適當提高系統的可復用性,同時提高了系統的可擴展性。系統的可擴展性由“開-閉”原則、里氏代換原則、依賴倒轉原則和組合/聚合復用原則保證。
3.適當提高系統的可復用性,同時提高了系統的靈活性。系統的靈活性由“開-閉”原則、迪米特法則、接口隔離原則保證。
4.適當提高系統的可復用性,同時提高了系統的可插入性。系統的可插入性由“開-閉”原則、里氏代換原則、組合/聚合復用原則和依賴倒轉原則保證。
復用的成功之路
那么我們如何做到正真的面向對象設計的復用呢?上面所講的內容都是工具,如果你認真的看完了,你已經擁有了復用的工具,復用是否成功就要看我們如何利用工具幫助我們在系統的生命周期中來實現。不要為了復用而設計系統,那么你會很累。給你提幾個意見:
a.多次驗證并被應用
你可以嘗試可復用的設計,但是直到你的設計被復用多次,你才可以談成功的設計。可復用性是旁觀者來下結論的,而不是設計者自己。
b.可復用性必須有完備的文檔
文檔必須標識出,什么時候不要復用它,這樣開發者才能理解合適場景的上下文。
c.復用是一種態度
當你設計新的系統架構的時候,第一件事應該是決定你的架構還會以怎樣的方式在別的場合被復用。也許有些人已經設計了你需要的東西。另一方面,你得主動分享你的工作成果,這樣大家才可以復用它。一個好領隊會在團隊中持續地尋找復用點和提升、獎勵復用的機會。一個不錯的方式就是在從這樣兩個方面去尋找可復用的機會:模型評審過程中,尋找繼承和模式復用的機會;代碼走讀過程中,尋找組件和代碼復用的機會。
提交成功!非常感謝您的反饋,我們會繼續努力做到更好!
這條文檔是否有幫助解決問題?
售前咨詢
售后咨詢
備案咨詢
二維碼
TOP