国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

讀《代碼不朽:編寫可維護軟件的10大要則》

2019-11-08 19:26:11
字體:
來源:轉載
供稿:網友

代碼不朽:編寫可維護軟件的10大要則(java版) 因為本科并非軟工和計算機專業,所以對軟件工程中的一些概念理解欠缺。我的編程實踐大部分來自于圖像處理算法程序的編寫,在編程過程中對代碼規范,軟件設計方面考慮較少。如果要成為一個專業的程序員,就需要學習已形成工業化的軟件構建方式。

可維護性解釋

這本書解釋了可維護軟件中的“維護”的意思:可維護性是軟件質量的一個標準,代表一個系統可被修改的難易程度。所以它是面向程序員的,假設兩個軟件完成相同的功能,但一個軟件的源碼,讓其他人或者一段時間之后的自己,很難理解,更不用提修改了,就說明這個軟件的可維護性比另一個差。維護的工作包括發現并糾正bug(糾正性維護);適應操作系統或運行環境的改變(適應性維護);根據需求增加新的功能(完善性維護);改進代碼質量預防bug產生(預防性維護)。

對10大要則的理解

按照從小到大,從細微到宏觀的層次,這本書提取了編寫可維護軟件中10大編程原則,小到程序開發者應當時刻注意的代碼規范,大到系統架構師應該考慮的系統重構、組件和及接口的設計準則。

編寫短小的代碼單元

代碼單元即面向對象編程里的方法或函數。這個原則要求每個函數的長度不應超過15行。

動機

小的函數的好處?作者提出,小的函數容易重用,因為一個巨型的方法會包含很多細節,導致很難有一模一樣的場景使用這個方法。作者提出,小的方法更易理解和進行單元測試。若超過15行,則意味著方法可以被拆分了。

如何使用本原則

拆分重構的方式有提取方法將方法替換為方法對象。 提取方法很容易理解,即從一個函數中提取一段代碼,寫成一個新的方法。但如果提取方法時發現,這個方法訪問了很多局部變量,如果都作為新方法的參數的話,勢必會導致參數列表過長。還有返回值的問題,如果這個方法會產生不止一個結果變量,那么這個方法就無法構建,因為java中一個方法只能有一個返回值。一個重構技巧是將這個方法替換成一個方法對象,將不同的局部變量和結果變量作為類的成員,然后調用類方法。

編寫簡單的代碼單元

這里的“簡單”體現代碼單元的分支點,所以這個原則可量化為:限制每個代碼單元分支點的數量不超過4個。Java中常見的分支點代碼就是if和switch語句。

動機

讓代碼單元保持簡單基于兩個原因,一是簡單的代碼更容易修改,二是簡單的代碼更容易測試,分支點過多,意味著要有更多的測試用例。

如何使用本原則

復雜的代碼單元可能是因為其中包含很多互不相關的代碼塊,這種情況可以采用“提取方法” 若是其它復雜的情況,比如碰到鏈式的條件語句,如下判斷國旗的語句:

...List<Color> result;switch(nationality) { case CHINA: result=Arrays.asList(Color.RED,Color.YELLOW); break; case FRENCH: result=Arrays.asList(Color.BLUE,Color.WHITE,Color.RED); break;...}

第一種方法是引入Map數據結構,將國家映射到指定的FLAG對象上; 第二種方法是使用“使用多態來代替條件判斷”,實現同一個接口,代表廣泛的國旗類型,然后為每個國家的國旗實現一個類。 再比如碰到嵌套的條件語句,為了使代碼簡單,可以使用“使用衛語句來代替嵌套的條件語句”的重構技巧,即標識出各種獨立的情況,并插入return語句來代替嵌套式的條件語句。 例如

if(...) { if(...) { //TODO CASE1 } else { //TODO CASE2 }} else { //TODO CASE3}

可以改寫成

if(...) { //TODO CASE1 return;}if(...) { //TODO CASE2 return;}if(...) { //TODO CASE3 return;}

可以看到分支點并未減少,然后可以再用“提取方法”減少復雜度。

不寫重復代碼

對重復代碼的定義是,一段至少6行都相同的代碼。

動機

如果復制代碼,相同的代碼出現在不同的地方,不利于源碼的定位;如果需要修改的地方正是重復的代碼,意味著要做很多重復性的工作,而且容易出錯。

如何使用本原則

首先想到的是提取方法;但若是一個方法是另一個類的私有方法怎么辦?這時應當將提取的方法放到一個工具類中。 如果重復代碼(6行以上完全相同)已不存在,但代碼相似,具有相同的邏輯,這時應該考慮提取父類。

保持代碼單元的接口簡單

限制每個代碼單元的參數不能超過4個。

動機

較少的接口參數能夠保持簡單的上下文,易于重用、理解和修改。

如何使用本原則

將多個參數包裝成對象,比如輸入坐標參數,xy,可以包裝成一個點對象。 使用“使用方法對象替換方法”的重構技巧,此處和前面有重合。

分離模塊之間的關注點

模塊對應類的概念。 實際上就是要求類要保持小的體積,不要過大過復雜。

動機

小的體積的類帶來了類之間的松耦合,松耦合意味著類能更靈活的適應將來的變化。如果一個類做了很多事情,其耦合度會越來越緊,積攢大量代碼,導致代碼很難閱讀和修改。

如何使用本原則

第一種方法:根據功能將大類拆分為很小的類。一個類一開始可能很小,只是實現單一功能,但都不可避免負責越來越多的職責,當意識到這個類承擔了不止一個職責時,就應該將這個類進行拆分。 第二種方法:提取一個接口,實現松耦合。比如一開始為一臺相機設計了簡單的相機類,只具備拍照,閃光燈打開和關閉3個方法。后來這個類的使用擴展到新的移動設備上,增加了定時功能。這時類變大,而且只有一個類,還需要檢查舊設備上的代碼有沒有受影響。為了降低耦合度,可以使用一個接口,它只定義所有相機都需要實現的功能。 第三種方法:使用第三方庫和框架來替代自定義的實現。

架構組件松耦合

組件是比模塊(類)更高一層的單元,設計到系統的架構。此原則要求盡可能減少當前模塊暴露給(例如,被調用)其它組件中模塊的相關代碼。

動機

獨立的組件可以單獨進行維護,方便劃分職責,讓測試變得容易。

如何使用本原則

使用抽象工廠設計模式,簡單的講就是類的實例不能直接被創建(new一個),而是通過工廠類的方法返回。這種通用的工廠接口背后,隱藏了具體產品的創建過程。在這個環境下,產品通常都不止有一種類型。如果要使用其中的邏輯,需要通過創建通用的工廠對象調用類方法成員。 注:抽象工廠不同于工廠模式,簡單理解就是抽象工廠的類型不止一個,所以產品至少有兩個。參見抽象工廠模式和工廠模式的區別?-caoglish的回答-知乎

保持架構組件之間的平衡

保持源代碼中的組件數量接近于9。

動機

好的組件平衡讓查找和分析代碼更容易,提供清晰的功能邊界,分離維護職責。

如何使用本原則

軟件系統的開發有兩種組織模式: 基于功能領域劃分的系統:好處是可以從高層功能的角度來分析代碼,壞處是技術人員需要了解多個技術棧 基于技術劃分的系統:根據技術專長來劃分,可能會有前端,后端,接口、日志等組件。 軟件架構師需要選擇如何組合功能的合適原則。明確系統的領域并堅持下去。

保持小規模代碼庫

動機

大型系統更加難以維護,易出現更密集的缺陷,以大型代碼庫為目標的項目更容易失敗。

如何使用本原則

功能層面:控制需求蔓延,功能標準化 技術層面:不要復制黏貼代碼,重構代碼,使用第三方庫和框架(這同樣是前面提到的準則)

自動化開發部署和測試

測試包含單元測試、集成測試、端對端測試、回歸測試、驗收測試。不同類型的測試需要不同的自動化框架。

動機

自動化測試可重復,有效率;自動化測試里的斷言(assert)可以充當注釋;通過編寫測試可以反過來推促編寫可測試的代碼,提高代碼質量。

如何使用本原則

使編寫單元測試成為每個開發人員的職責,比如使用Java中的單元測試框架jUnit。 使用像stubbing或者mocking這樣的技術。stub即測試樁。需要測試樁是因為有些影響測試結果的測試條件是易變、無法統一的。比如拍照,兩次拍攝的環境不可能完全相同,結果無法驗證,所以需要一個假對象,即測試樁。mocking(模擬)是因為測試中某些函數是沉默的,不包含任何結果,可以在函數中添加計數來驗證函數執行過。mock技術有自動化的框架。 建議生產代碼和測試代碼一比一,提高覆蓋率。

編寫簡潔的代碼

給程序開發人員總結了7條“童子軍軍規”: 1、編寫單元級別的良好代碼 2、不要編寫不好的注釋 3、不要注釋代碼 4、不要保留廢棄代碼 注:包括3,同時還有其它的形式,比如不可能執行到的代碼、無用的私有方法、注釋中的代碼 5、不要使用過長的標識符名稱 6、不要使用魔術常量 注:指表達式中突兀出現的數字,應該先定義。 7、不要使用未正確處理的異常 注:包括以下情況,捕獲異常卻不處理(catch為空),直接捕獲通用異常(比如RuntimeException異常,這些異常不會提供觸發失敗的狀態或事件信息,所以沒意義),將異常信息展示給終端用戶(避免用戶困惑或暴露信息,應該先轉換為通用信息)


上一篇:STL之set

下一篇:A1022. Digital Library

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 淮安市| 金寨县| 郧西县| 定西市| 定结县| 江山市| 静安区| 广平县| 广宁县| 田林县| 芒康县| 昔阳县| 杨浦区| 灯塔市| 河曲县| 大名县| 茂名市| 治县。| 藁城市| 筠连县| 庆云县| 陕西省| 钦州市| 谢通门县| 开平市| 长顺县| 台山市| 黄浦区| 宁夏| 华亭县| 恩施市| 岳阳市| 汉源县| 象州县| 普宁市| 京山县| 昌图县| 石楼县| 长垣县| 红河县| 阳曲县|