999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

面向設計的開源軟件項目重構經驗研究*

2017-09-18 00:28:53趙文耘
計算機與生活 2017年9期
關鍵詞:設計研究

阮 航,陳 恒,彭 鑫+,趙文耘

1.復旦大學 軟件學院,上海 201203 2.復旦大學 上海數據科學重點實驗室,上海 201203

面向設計的開源軟件項目重構經驗研究*

阮 航1,2,陳 恒1,2,彭 鑫1,2+,趙文耘1,2

1.復旦大學 軟件學院,上海 201203 2.復旦大學 上海數據科學重點實驗室,上海 201203

技術債;軟件設計;重構;開源項目

1 引言

在現實世界中,軟件不是一成不變的。隨著時間的推移,軟件一直在不斷演化。演化的原因可能包括增加新需求,修改原有功能,刪除無用功能,修復軟件漏洞或者改善軟件性能等。代碼量在軟件演化過程中變得愈來愈龐大,代碼結構也愈來愈復雜,偏離了最初的設計方向,軟件的質量和可理解性也會降低。此時如果不及時對軟件進行重構,會給后續開發帶來許多困難和阻礙。

重構是在不改變軟件外部行為的條件下,對軟件內部結構的一種調整,提高軟件的可理解性,降低其修改成本[1]。重構可以改善軟件的設計,提高代碼的可理解性,幫助開發人員定位bug位置,使程序員能夠更加快速地開發軟件[1]。在實際軟件開發過程中,重構逐漸占有越來越重要的地位,特別是在敏捷開發和極限編程實踐里。極限編程團隊通過周期性的重構來扭轉軟件退化,并循環持續進行重構[2]。

項目開發之初會對高層架構進行設計,后續開發中根據設計的架構完成項目的編碼工作。一份好的設計可以讓開發者輕松地完成工作,相反一份不好的設計會使開發者在面對同樣的工作時付出更多的勞動。在實際開發過程中,即使有良好的設計,但為了盡早交付軟件產品,開發人員往往會犧牲代碼質量,破壞原有的設計。這就是技術債,長遠的債務需要在維護階段花費更多的人力去補償。

重構是否真的可以改善代碼質量,重構在實際軟件開發過程中的地位如何。針對這兩個問題,本文選擇兩個開源項目進行經驗研究,主要有兩個關注點:(1)實際項目中重構出現的頻率和類型,其中面向設計的重構在所有重構中是否是重要的一部分;(2)不好的設計是否真的對軟件開發造成了困難和阻礙,這種情況在開源項目中是否真實存在,如果對其進行合理的重構,是否有利于后續的開發。

本文組織結構如下:第2章簡要概述本文的相關工作;第3章通過一個使用策略模式進行重構的例子證明重構的重要性,繼而介紹重構的相關概念;第4章描述研究的問題,介紹選取的研究對象以及選取原因,并說明數據收集方法;第5章根據收集到的數據回答研究問題并得出結論;第6章對研究中的發現和不足之處進行討論;第7章總結全文。

2 相關工作

下面從重構和技術債兩部分介紹相關工作。重構部分介紹目前學術界對重構的相關研究;技術債部分描述了設計相關的技術債的研究工作,說明了不良設計問題對于軟件開發和維護的阻礙。

2.1 重構

眾多學者對重構的時機和分類已經進行了研究。Fowler[1]的工作總結了22種代碼壞味道幫助定位重構機會,總結了一系列重構類型,以及指導怎樣合理進行重構。Gamma等人[3]分類整理了共23種設計模式,幫助開發者設計出更加靈活的、模塊化的、可復用的和易理解的軟件。Kerievsky[4]在前兩者的基礎上把重構與模式結合起來進行考慮,描述了模式導向的重構。

Mens等人[5]對目前為止軟件重構技術進行了總結,對每個重構階段的相關研究都進行了介紹,并分析了目前研究出的技術和工具。Mens等人[6]指出未來重構面臨的問題是基本原理問題和實踐問題。

代碼壞味道會阻礙軟件演化,開發歷史中對代碼壞味道的修改明顯多于其他部分[7-8]。Munro[9]提出了一種通過使用度量值的集合自動監測代碼壞味道的方法。

M?ntyl?[10]發現處于領導級別的工程師更關注于較高層次的代碼壞味道,而且在項目中經驗豐富的人員能發現更多的代碼壞味道;人工進行的代碼壞味道甄別和現有的度量產生了沖突。Kataoka等人[11]設計了一款通過程序不變量來挑選出代碼壞味道并進行重構的工具。

現有研究面向的重構操作大都是簡單的原子性操作,當需要完成比較高級的復合型操作時,仍舊需要人工進行輔助。

2.2 技術債

技術債由Cunningham首次提出,指的是開發團隊在設計或架構選型時從短期效應的角度選擇了一個易于實現的方案,但從長遠來看,這種方案會帶來更消極的影響,亦即開發團隊所欠的債務[12]。

在技術債相關信息不明確的時候,Guo等人[13]對技術債的問題嚴重性,技術債是如何影響軟件項目和技術債影響軟件項目的哪些方面進行了探索。Schmid[14]提出應該用一系列近似值來模擬各個方面,然后慎重決定技術債。Tom等人[15]對技術債提出了一個完整的理論框架體系。

Ernst等人[16]通過對現實生活中1 800多位工程師和架構師的調查和訪問,分析技術債的相關問題。結論顯示技術債是一個有意義且容易理解的抽象比喻,工程師們一致同意設計結構是造成軟件技術債的主要原因。如何處理和管理技術債目前仍然存在諸多困難,但他們認為從原始設計追蹤有助于解決這一問題。

3 案例介紹

本章通過一個計算顧客購物清單應支付金額的案例,介紹重構相關的基本知識,展示結構設計對于軟件演化的影響,以及利用重構進行結構調整對于軟件后續開發的益處。

3.1 案例描述

案例的大致結構如圖1所示,圖中展示了一個在商場中付款時,用來計算顧客購買貨物應支付金額的類Payment。

Fig.1 Payment class structure圖1 Payment類結構

用戶分為3種:(1)有等級并可以使用積分的用戶;(2)有等級但不可以使用積分的用戶;(3)無等級的用戶。有等級的用戶可以享受對應的等級打折優惠,并且可以使用積分來抵消掉一部分的消費金額。

3.2 問題分析和解決

這個計算支付金額的案例存在設計缺陷。設計最大的缺點是當對原有功能進行擴展時會遇到很多阻礙,比如需要根據顧客所選擇的支付方式提供一些不同的優惠政策,這些優惠有著不同的計算方式。如果采取圖1所示的設計方法,需要修改大量的分支代碼。這樣的設計會令后續的功能擴展更加困難,當出現復雜的邏輯判斷時,往往需要進行重構來減少程序復雜度。

面對圖1中所展示的結構,適用于使用策略模式進行結構上的改進和優化。應用策略模式令客戶端的代碼與實際的算法分離,便于對原有算法進行修改以及增加新算法等。在應用策略模式后,調整后的設計結構如圖2所示。

此設計的優點在于可以使計算模塊和客戶端分開,當需要增加新的計算方式時,可以直接在服務端進行修改,客戶端可以很簡單地通過調用新增的策略來實現,對客戶端的修改量很小。例如需要根據顧客所選擇的支付方式提供一些不同的優惠政策時,所要進行的修改只是去增加繼承自GetBillStrategy抽象類的一種新的計算方式策略類。重構可以幫助開發者改善代碼結構,更加有益于新功能的添加和后續的維護工作。面對同樣增加新功能的需求,優化后代碼所需要進行的修改量遠遠少于未進行優化的代碼。

接下來,對研究中出現的重構進行介紹。

Fig.2 Payment class structure after using strategy mode圖2 應用策略模式后的Payment類結構

3.3 重構操作介紹

如前文曾經介紹過的,現有重構的命名都是基于文獻[1]進行的,本文按照重構是否涉及軟件設計和難易程度將重構分為3類:不涉及設計的重構、涉及設計的簡單重構和基于設計模式的重構。

這里所說的是否涉及到設計,采用如下判定方式:所應用的重構方式是否改變了原有的類結構,包括類在包中的位置、類與類之間的依賴關系等,這樣的變化可以通過類圖直觀地展現。

3.3.1 不涉及設計的重構

提煉函數,替換算法,分解/合并條件式,重新命名函數/重新命名屬性等重構方法是在實際研究過程中觀察到的不涉及軟件設計的重構。不涉及設計的重構的操作比較單一,多數是一些簡化和移動操作。

3.3.2 涉及設計的簡單重構

搬移函數,提煉類,用多態替換條件式,函數上移/下移,提煉父類等重構方式都涉及到對設計的優化與改進,其中一些實現是由比較簡單的重構所構成。

3.3.3 基于設計模式的重構

設計模式是經過分類的反復使用的代碼設計經驗的總結,可以方便進行后續的代碼復用。設計模式的應用會伴隨著新的輔助類的添加或者是對現有類的結構調整,是一種比較高級的重構方式。

4 研究方案

本章對研究的整體過程進行介紹:首先說明研究所關注的兩個問題;其次介紹選取的研究對象,并解釋選取研究對象的原因;最后介紹數據收集的方法。

4.1 研究問題

本研究的目的在于發現重構在現實項目中是否有廣泛的應用,研究面向軟件設計的重構在所有重構中的重要性,以及分析重構是否會改善軟件設計。在對開源項目的研究中,主要關注以下兩個研究問題。

問題1重構在現實項目中是否有很多應用,其中是否出現了面向設計的重構。

研究問題1的主要目的是研究在開源項目中開發人員對重構的重視程度,并且在其中發現開發人員對面向軟件設計的重構的關注度。在版本歷史中,研究開發人員是否發現重構機會然后進行重構,可以了解重構在開源項目中是否被認可和應用,其中面向軟件設計的重構的比例可以顯示出這類重構是否是重要的一部分。

問題2在現實項目中,是否存在由于未進行重構改善不良設計,導致后續開發過程中遇到了不必要的障礙的情況,以及后續是否意識到并進行重構。

研究問題2的主要目的是研究面向設計的重構的影響,關注點在于開源項目中是否真實存在這樣面向設計的重構。當存在這樣的重構機會時,觀察在后續沒有進行重構的這一段開發過程中,開發人員是否因為這樣的不良設計遇到了不必要的困難。如果在開源項目中找到了面向設計的重構,通過研究重構前的開發階段,考慮面向設計的重構是否可以解決這些阻礙。

4.2 研究對象介紹

本文選取jEdit和Jabref兩個開源項目作為研究對象。選擇這兩個開源項目的原因有以下兩點:(1)這兩個開源項目使用Java語言編寫,Java語言是一種面向對象的高級編程語言,出現重構機會的可能性更高;(2)項目規模較小,更利于理解代碼結構和內部邏輯。

4.2.1 jEdit

jEdit是一款比較成熟的開源程序員文本編輯器,由Slava Pestov在1998年進行主要內核的開發,目前內核大致穩定沒有繼續修改,但仍有很多開發者在制作和更新相應插件。

4.2.2 Jabref

Jabref是一個用Java語言編寫的支持多平臺的文獻推送和管理工具,2005年開始開發,到目前為止仍在持續開發和更新。

4.3 數據收集

在對這兩個開源項目的研究中,分別選擇了3個版本間的所有提交作為研究對象。jEdit選擇了jedit-4-3-pre16至jedit-4-3-pre17和jedit-4-3-pre17至jedit-4-3-pre18兩個階段;Jabref選擇了v2.11至v2.11.1和v2.11.1至v3.0兩個階段。在選擇了研究目標后,對數據進行了預處理,最后采用人工閱讀的方式收集所需數據。

4.3.1 數據預處理

由于開源項目的提交次數多,修改的文件之間的關系復雜,人工閱讀所有提交歷史并統計數據是不現實的。針對這個問題,對這兩個項目的各個階段設計了對應的數據庫表結構來儲存相關信息,方便查詢和統計。在數據庫上進行的數據統計需要基于人工閱讀的經驗。

4.3.2 人工閱讀

人工閱讀開源項目的提交歷史是本文經驗研究的主要方法,在人工閱讀過程中主要關注兩個研究問題。

問題1主要面向的對象是開發項目過程中開發人員實際做出的重構操作,并要關注其中涉及到軟件設計的部分。對于這個研究問題,在人工閱讀過程中需要注意觀察提交日志帶有refactoring關鍵字的提交。同時需要通過閱讀源碼發現未標明的重構,結合提交信息和具體的修改內容人工判斷每次提交的意圖,了解是否應用了重構操作,以及是否存在面向設計的重構。

問題2主要研究的是開發的某段過程中是否存在不好的設計,使后續開發遇到了不必要的困難。這個問題采用兩種思路進行研究:第一種思路是在閱讀前對項目的各個模塊進行大致的理解,了解程序的運行流程和互相之間的調用處理關系,在這個基礎上尋找不好的設計,并追蹤這個設計對于后續開發的不良影響。第二種思路是先尋找到開發人員已經進行過的面向設計的重構,在這次重構的提交基礎上回溯檢查此次提交前的提交,從而發現沒有進行改善設計的重構前,開發過程中是否遇到了阻礙。

5 結果分析

本章對研究結果進行分析。數據來源于兩個開源項目的4個開發階段,在后文中表示如下:jEdit的jedit-4-3-pre16至jedit-4-3-pre17階段表示為pre1617,jedit-4-3-pre17至jedit-4-3-pre18階段表示為pre1718;Jabref的v2.11至v2.11.1階段表示為v11to111,v2.11.1至v3.0階段表示為v111to3。

5.1 問題1

所有提交在數據庫統計中發現,有一部分不包含java文件,修改的是用于記錄的log文檔、配置文件等,可以通過文件類型進行排除。在排除了無關的提交后,pre1617、pre1718、v11to111和v111to3的提交次數為230次、134次、58次和278次。

在這些提交中,搜索“refactoring”和“restructure”關鍵詞發現包含重構的提交。jEdit項目在pre1617中出現了1次標明重構的提交,Jabref在v111to3中出現了7次標明重構的提交(排除了對測試用例重構的提交)。但在后續的人工閱讀階段發現,重構操作遠不止搜索到的8次提交,這一情況說明現在開發人員對于重構操作的認識不夠,但是開發人員實際上進行了一部分自身沒有意識到是重構的操作。例如:一個搬移getBoolean方法的重構被開發人員描述為“New method StandardUtilities.getBoolean()that will convert an object into a Boolean”,只提到了新方法的添加,沒有體現該方法移動到StandardUtilities類中。兩個項目中標明為重構的共8次提交中有2次是提煉函數重構,其余6次是重命名重構,這些都是簡單的重構類型,并且這些重構大多只涉及一個類的修改。說明開發人員對于部分簡單重構是有一定的理解的,或者說開發人員更認可同一個類中進行的重構。

jEdit的開發時間要遠遠早于Jabref,所研究的jEdit開發階段的時間在2008年11月至2009年11月,Jabref所研究的開發階段在2015年11月,這證明了重構的重要性正一步步被認可,提交日志中注明“refactoring”或“restructure”關鍵字的提交逐漸變多。

pre1617、pre1718、v11to111和v111to3所包含的重構次數分別為31次、8次、19次和43次。在jEdit中平均有10.71%的提交是關于重構的,在Jabref中平均有18.45%的提交是關于重構的,這些數據說明了重構在開發中的重要性,開發人員進行了不少沒有意識到的重構。

開發人員進行過的重構主要有8種類型,分別是搬移函數、提煉類、方法上移、改變參數、搬移值域、重命名函數或屬性、替換算法、提煉方法和自封裝值域。所列舉的前5種重構會涉及到軟件設計的調整,因為這些重構會更改類之間的調用關系或層次結構。

各個種類的重構操作在pre1617、pre1718、v11to111和v111to3中的比例如圖3所示,明顯看到重命名和搬移函數重構操作在各個研究階段分布較多。重命名和搬移函數重構的經常出現表明,在開發過程中對類的職責劃分不清晰。重命名重構以下的部分表示面向軟件設計的重構操作,面向軟件設計的重構在每個階段所占比例大約在50%左右,pre1718因為包含了較少的重構操作(8次),所以被排除在外。從這個比例可以看出,面向設計的重構操作在所有重構中占有較高比例。

Fig.3 Refactoring classification ratio圖3 重構分類比例

研究中觀察到的面向設計的重構操作包含搬移函數、提煉類、方法上移、改變參數和搬移值域。這些重構有一個共同點:在重構中涉及到的修改的類大多只有兩個。這說明目前觀察到的涉及軟件設計的重構是比較簡單的重構,只是兩個類之間的結構的分配,沒有比較復雜的涉及多個類結構的重構出現。

重構在實際項目中有著重要的應用,項目中對其關注度也越來越高。但是目前開發人員對于重構的認知度偏低,對實際上是重構操作的提交很少進行注明。開發人員對于重命名等簡單重構已經有普遍認知,基本能夠主動標識。面向軟件設計的重構在重構中出現頻率較高,主要是在兩個類之間進行相關的函數和屬性搬移,調整類的層次結構等簡單重構,但沒有應用設計模式的復雜重構出現。

5.2 問題2

由于未及時重構,不合理的設計對后續開發造成了阻礙的情況是存在的,但是其中的大部分沒有被合理地重構或者處理方式不合適。下面通過兩個最典型的例子進行分析研究,并展示合理的重構對后續開發的積極影響。其中5.2.1小節中的例子被開發人員識別出重構機會并進行了重構,5.2.2小節中的例子沒有進行重構。

5.2.1 保存對話框尺寸的設計

Jabref的圖形化界面模塊中存在一個包gui,專門用來保存與界面相關的對象,其中一部分對象用來表示對話框。有一個對話框類DuplicateResolverDialog實現了用于保存位置和大小信息的方法savePosition。

此處出現了設計缺陷,保存對話框大小和位置信息的方法屬于通用的設置方法,很有可能被同樣是對話框的其他類復用。并且在DuplicateResolver-Dialog的init初始化方法中有一段代碼的意圖是設置對話框的大小和位置信息,這樣獨立的操作沒有提煉成方法。

在后續的開發中,id為313bf3b的提交中出現了新的需求:為MergeEntryDialog類和MergeEntry-DOIDialog類添加保存對話框大小和位置的功能。按照之前較差的設計,開發人員實現的方式就是在MergeEntryDialog類和MergeEntryDOIDialog類中增加savePosition方法。實現與DuplicateResolverDialog類相同,同時初始化中設置初始大小和位置的功能也同樣實現,結構如圖4所示。按照這樣的設計,后續的向其他對話框類中添加相同方法時需要不斷地增加新方法,修改初始化方法,會產生大量的冗余代碼。此外一旦需要對這個方法的邏輯進行修改,就不得不對每個實現該方法的對話框類進行修改,增加了維護和修改的成本。

Fig.4 Irrelevant dialog structure圖4 無關聯的對話框結構

id為c47fe58的提交中發現了這個問題,對于結構的調整是提取savePosition方法為GUIGlobals的靜態方法,并通過重命名函數和增加參數的重構修改為storeDialogSize方法。與此同時,設置大小和位置的代碼塊提取出來成為GUIGlobals的靜態方法set-DialogSize,結構如圖5所示。在id為c582705的提交中對這一部分又進行了重構,提煉單獨的Position-Window類來維護這兩個靜態方法用以調用。

Fig.5 Dialog structure after refactoring in project圖5 項目中重構后對話框結構

這樣的設計改進是可以消除冗余代碼和減少后期維護難度的,但不是最好的面向對象的解決辦法。提取方法作為靜態方法的處理方式破壞了面向對象的理念,很難利用多態處理相關問題。在研究中發現有十幾次類似的通過將方法提取到通用類中改為靜態方法的方式處理相似問題,這樣的處理方式并沒有對設計進行修改,開發人員考慮到修改后的測試成本和軟件的正確性問題等多方面原因,選擇最簡單的增加靜態功能的方式進行處理,沒有從根本上改善設計問題。

設置和存儲對話框大小位置信息的功能在邏輯上與對話框類聯系緊密,應該作為對話框類的方法實現。一個較好的改進方案是為需要實現該功能的對話框實現統一的父類,其中storeDialogSize和set-DialogSize方法,實現該功能的類繼承自這個父類獲取該方法的實現,重構后結構如圖6。這樣不僅可以消除冗余代碼,而且當特別的子類需要有特別的邏輯修改時還可以通過覆寫的方式修改,改善了代碼的可維護性和可擴展性。

Fig.6 Dialog structure after reasonably refactoring圖6 合理重構后對話框結構

5.2.2 模式選擇的設計

Jabref在搜索部分需要選擇不同的搜索模式而使用不同的策略進行搜索,設計的方式是使用一個枚舉類型的SearchMode保存相關內容,在SearchBar通過對應的RadioButton來進行切換選擇策略。Jabref沒有進行很好的設計,導致有大量switch和if…else…語句出現在方法中,主要表現在initSearchModeMenu、getSearchModeMenuItem、getSearchMode、focus和 on-SearchTextChanged這5個方法中。

在id為a1b231e的提交中,為了更簡單地進行搜索模式的選擇,搜索模式需要從原有的6種減少到3種。面對這樣的新需求,SearchBar類需要在上述5個方法中做大量的修改,如圖7和圖8所示為get-SearchModeMenuItem方法修改部分。其他的方法也都包含關于這幾種模式的選擇判定的switch或if…else…語句,同樣需要進行大量分支的刪除,重復出現的判斷對后續修改造成的困難展露無遺。

Fig.7 Function getSearchModeMenuItem before changing圖7 修改前getSearchModeMenuItem方法

這個設計問題可以通過應用狀態模式解決。后文對簡化后3種模式的實現進行優化分析,設計結構調整如圖9。

Fig.9 SearchBar structure after refactoring圖9 重構后SearchBar結構

在沒有應用設計模式的重構前,實現對搜索模式的增刪修改時,需要對SearchBar類中涉及到模式類型判斷的方法進行大量修改,同時需要修改用于維護信息的SearchMode類。如果能及時應用本文所調整的結構,增刪模式的操作變得極為簡單。當需要變更模式類型時,只需要增加SearchMode對應的模式實現,并修改SearchBar的初始化方法實現對應按鈕的添加,再在Globals存儲的模式數組中添加名稱字符串,就可以完成模式的增刪,不需要在項目中修改大量的方法,同時可以減少大量判斷語句的使用,提高代碼性能,代碼結構也更加清晰易懂。

Fig.8 Function getSearchModeMenuItem after changing圖8 修改后getSearchModeMenuItem方法

6 討論

本章介紹在研究過程中產生的思考以及研究中存在的不足。

6.1 不良設計的出現與原因

不良設計是導致代碼質量下降的重要原因之一,阻礙開發人員對軟件的開發和維護。及時利用重構改善不良設計是理想的處理方法,可以降低不良設計對后續開發造成的危害。研究中發現不良設計的出現與原因可以總結為3種情況:

(1)在軟件設計階段產生的不良設計。軟件架構師不可能設計出絕對正確的軟件設計,這種不良設計的出現是無可避免的。

(2)由于技術債產生的不良設計。由于人力、時間和資源等因素的限制,開發人員無法在要求的短期時間內交付可展示的工作成果。為了及時交付工作成果,開發人員往往選擇舍棄部分設計以在短期內完成工作,也就是軟件工程領域的技術債問題。面向設計的技術債屬于開發人員不得不因為現實因素做出讓步的一種決策。

(3)在開發過程中產生的不良設計。軟件開發是一個漫長的過程,期間會出現無數次的功能增加與變更。功能的增加與變更會改變原有的類結構,這會暴露出目前設計的問題。這種問題在設計之初可能不是一個不良設計,在后續的修改過程中才變成了不良設計。

考慮5.2.1小節的例子,最初只有DuplicateResolver-Dialog這一個對話框類實現了保存對話框大小的功能,僅在該類中維護相關方法是合理的。如果在設計之初設計成繼承父類方法的方式,會使其他對話框類出現不必要的方法,父類在整個結構中顯得多余。當增加MergeEntryDialog類和MergeEntry-DOIDialog類后,才發現原來設計的不足之處,需要消除冗余代碼。

了解不良設計的出現階段和原因能夠幫助對不良設計進行追蹤和記錄,有利于為后續維護和修改提供有益信息。

(1)和(2)中產生的不良設計可以通過審查和記錄的方式發現問題所在,但(3)中產生的不良設計需要在開發中定期進行重構才可以解決。

6.2 重構的價值和面臨的問題

經過研究,開源項目歷史中已經存在重構相關的提交,面向設計的重構在所有發現的重構中占有接近一半的數量,是重構中重要的一部分。面向設計的重構可以提高可理解度,也能夠減少冗余的代碼,降低代碼的維護難度。如果在開發過程中自覺地進行重構,可以為以后的開發降低難度,提高效率。

但重構仍然面臨一些問題:首先是對重構的認知,目前開發人員對于重構普遍只處于聽說過的階段,并不了解重構的具體內容,這使重構難以系統地進行;其次是重構的效益,重構后代碼的優點更多體現在后續的開發過程中,這種未來效益很難得到重視;面向設計一類的復雜重構不僅修改一個類,常常涉及到幾個類的變動,其間難免會出現漏洞,這樣的修改成本和測試成本是開發人員不愿意承擔的,因此開發人員更偏向于改動單一的類來完成需求,不會自覺地進行較為復雜的重構。

開發人員對重構的不理解,管理人員對重構的輕視和重構成本過高,是無法進行重構的主要原因。通過自動判定應當應用重構的位置和自動應用重構后,重構的價值可以更好地體現,降低重構難度和成本,重構才能真正應用到每個開發過程中。

6.3 研究不足

研究可能會因為以下幾個因素導致研究結果不準確,主要包括對面向設計的重構的識別,研究對象的選擇和開發階段的識別3個因素。

6.3.1 重構分類準確性

對于現有的重構操作,本文按照重構是否改變了軟件設計將其分為3類,主要判斷依據是重構是否改變了軟件類之間的依賴關系,使用類圖展示可以清晰地辨別出這種變化,但是有一部分重構無法準確判斷是否改變了設計。

以添加參數的重構為例。添加參數的重構在研究中被定義為面向設計的重構操作:第一種情況也是大多數情況,是在A類的方法中增加了B類的參數,這樣就更改了類與類之間的依賴關系,這樣的操作認為是面向設計的重構。第二種情況是,在A類中添加了A類自身屬性作為參數,這也屬于添加參數的重構,但不改變類之間的關系,這一情況在研究中出現得不多,因此仍然認為添加參數是面向設計的重構。在研究中遇到第二種情況時,并不統計為添加參數的重構,僅僅統計入重構總次數。

6.3.2 研究對象選擇

研究中選取了兩個項目,jEdit開發時間比Jabref更早。這里可能出現的問題是研究選取的對象太少,在兩個開源項目間的統計和比較可能不具有普遍性,但是在研究項目中發現的實例確實可以證明不良設計對于軟件開發的不良影響,而且驗證了重構對于改善設計的重要作用。

6.3.3 版本選擇問題

本文在每個開源項目的兩個開發階段通過統計和閱讀源碼的方式進行研究,開發階段的選取是隨機的。這樣選取開發階段可能會存在問題,jEdit是保持內核基本不變的開源項目,選取的階段可能設計已經基本定型,暴露出的問題可能偏少,而處于不斷開發過程的Jabref項目中暴露設計問題的可能性更高。同時隨機化挑選也有一定優勢,隨機化挑選開發階段可以排除由于挑選開發活動頻繁的階段造成的結論特殊性。

7 結束語

軟件在現實世界中不是一成不變的,隨著時間的推移一直在不斷進行演化。為了解決各種原因造成的代碼設計問題,需要在開發過程中不斷進行重構改善代碼質量。

在對現有重構類型和應用場景已經有一定理解的基礎上,本文提出了兩個研究問題進行探索。研究中選取兩個開源項目作為研究對象,在每個研究對象上隨機選取兩個版本間的開發歷史作為觀察,通過數據預處理后人工閱讀的方式收集開源項目中的實際例證和數據進行問題研究。

研究證明重構是開發過程中重要的一部分,在研究的兩個開源項目的提交歷史中分別占有10.71%和18.45%的比例。雖然重構在項目中應用很多,但是開發人員在應用重構的過程中往往沒有意識到所做的操作是重構,沒有在提交日志中說明,提交日志中指明修改是重構的提交只占實際重構中極小的一部分。提交日志中指明本次修改是重構的提交中,主要的重構類型是重命名,這說明開發人員對于重構操作的類型和定義的了解只處于最初級的階段。面向設計的重構在所有重構中占據將近1/2的數量,是重構的一個重要方面。開發人員在開發中識別出并進行重構的面向設計重構只涉及兩個類之間的變動,操作過于簡單。

研究過程中發現了這樣的情況,由于未進行合理設計,導致進行功能擴展的過程中遇到了不必要的障礙,極少有開發人員意識到是設計問題并進行重構調整。但是所進行的重構并沒有在根本上解決設計問題,有時反而會導致其他設計問題的出現。研究通過提出合理的解決辦法,將合理重構方式與開發人員實際重構進行對比,體現出應用合理重構對于提高代碼質量的重要性,很大程度上改善了代碼的可維護性。軟件設計在開發過程中具有指導性意義,在演化過程中軟件設計的退化問題和技術債的管理問題往往需要應用重構去解決。

未來的研究需要找到合適的評價軟件設計質量的度量,從而指導在何時何處應用何種重構改善代碼設計,沒有指導的盲目重構是沒有意義的。目前沒有足夠的工具幫助開發人員管理面向設計的技術債問題,在未來對這些方面需要進一步的研究。

[1]Flower M.Refactoring:improving the design of existing code[M].Upper Saddle River,USA:Addison-Wesley Professional,1999:53-89.

[2]Martin R C.Agile software development:principles,patterns,and practices[M].Upper Saddle River,USA:Prentice Hall,2002:9-16.

[3]Gamma E,Helm R,Johnson R,et al.Design patterns:elements of reusable object-oriented software[M].Upper Saddle River,USA:Addison-Wesley Longman Publishing Co Inc,1995:241-276.

[4]Kerievsky J.Refactoring to patterns[M].Upper Saddle River,USA:Addison-Wesley,2002:232.

[5]Mens T,Tourwe T.A survey of software refactoring[J].IEEE Transactions on Software Engineering,2004,30(2):126-139.

[6]Mens T,Demeyer S,Bois B D,et al.Refactoring:current research and future trends[J].Electronic Notes in Theoretical Computer Science,2010,82(3):483-499.

[7]Khomh F,Penta M D.An exploratory study of the impact of code smells on software change-proneness[C]//Proceedings of the 16th Working Conference on Reverse Engineering,Lille,France,Oct 13-16,2009.Washington:IEEE Computer Society,2009:75-84.

[8]Olbrich S,Cruzes D S,Basili V,et al.The evolution and impact of code smells:a case study of two open source systems[J].Biology of Reproduction,2009,68(5):390-400.

[9]Munro M J.Product metrics for automatic identification of“bad smell”design problems in Java source-code[C]//Proceedings of the 11th International Software Metrics Symposium,Como,Italy,Sep 19-22,2005.Washington:IEEE Computer Society,2005:15.

[10]M?ntyl? M V,Vanhanen J,Lassenius C.Bad smells — humans as code critics[C]//Proceedings of the 20th International Conference on Software Maintenance,Chicago Illinois,USA,Sep 11-17,2004.Washington:IEEE Computer Society,2004:399-408.

[11]Kataoka Y,Notkin D,Ernst M D,et al.Automated support for program refactoring using invariants[C]//Proceedings of the 2001 International Conference on Software Maintenance,Italy,Nov 6-10,2001.Washington:IEEE Computer Society,2001:736-743.

[12]Cunningham W.The WyCash portfolio management system[J].ACM SIGPLAN OOPS Messenger,1992,4(2):29-30.

[13]Guo Yuepu,Seaman C,Gomes R,et al.Tracking technical debt—an exploratory case study[C]//Proceedings of the 27th International Conference on Software Maintenance,Williamsburg,USA,Sep 25-30,2011.Washington:IEEE Computer Society,2011:528-531.

[14]Schmid K.A formal approach to technical debt decision making[C]//Proceedings of the 9th International ACM Sigsoft Conference on Quality of Software Architectures,Vancouver,Canada,Jun 17-21,2013.New York:ACM,2013:153-162.

[15]Tom E,Aurum A,Vidgen R.An exploration of technical debt[J].Journal of Systems&Software,2013,86(6):1498-1516.

[16]Ernst N A,Bellomo S,Ozkaya I,et al.Measure it?manage it?ignore it?software practitioners and technical debt[C]//Proceedings of the 10th Joint Meeting on Foundations of Software Engineering,Bergamo,Italy,Aug 30-Sep 4,2015.New York:ACM,2015:50-60.

RUAN Hang was born in 1993.He is an M.S.candidate at Software Engineering Laboratory,Fudan University.His research interest is software maintenance and evolution.

阮航(1993—),男,遼寧凌源人,復旦大學軟件工程實驗室碩士研究生,主要研究領域為軟件維護與演化。

CHEN Heng was born in 1992.He is an M.S.candidate at Software Engineering Laboratory,Fudan University.His research interest is software maintenance and evolution.

陳恒(1992—),男,江蘇泰州人,復旦大學軟件工程實驗室碩士研究生,主要研究領域為軟件維護與演化。

彭鑫(1979—),男,湖北黃岡人,2006年于復旦大學計算機科學專業獲得博士學位,現為復旦大學教授,CCF高級會員,主要研究領域為需求工程,自適應軟件,軟件產品線,軟件維護,逆向工程。

ZHAO Wenyun was born in 1964.He received the M.S.degree from Fudan University in 1989.Now he is a professor at Fudan University,and the senior member of CCF.His research interests include software reuse,software product line and software engineering.

趙文耘(1964—),男,江蘇常熟人,1989年于復旦大學獲得碩士學位,現為復旦大學教授,CCF高級會員,主要研究領域為軟件復用,軟件產品線,軟件工程。

Empirical Study of Design-Oriented Refactorings in Open Source Projects*

RUAN Hang1,2,CHEN Heng1,2,PENG Xin1,2+,ZHAO Wenyun1,2
1.Software School,Fudan University,Shanghai 201203,China 2.Shanghai Key Laboratory of Data Science,Fudan University,Shanghai 201203,China

Software is constantly changing and evolving,driven by the increment of requirements.Software often degrades from the original design,the quality of codes also becomes poor.Developers will meet more barriers and difficulties in the future development when there are some technical debts in the original design.It is necessary to improve the quality of codes by refactorings.This paper introduces some common types of refactorings under the review of related literature,and introduces a simple case to verify the importance of the design-oriented refactorings.This paper aims to answer two questions:(1)whether there are applied refactorings in the open source project and whether there are design-oriented refactorings among them;(2)whether there exists some situation that the structure with a bad design causes difficulties in the fellow-up development and whether the developers apply some refactorings to it later.This paper proves the wide use and importance of refactorings in open source projects,particularly the importance of the design-oriented refactorings.

technical debt;software design;refactoring;open source project

the Ph.D.degree in computer science from Fudan University in 2006.Now he is a professor at Fudan University,and the senior member of CCF.His research interests include requirements engineering,self-adaptive software systems,software product line,software maintenance and reverse engineering.

2016-09, Accepted 2016-11.

A

TP311

+Corresponding author:E-mail:pengxin@fudan.edu.cn

RUAN Hang,CHEN Heng,PENG Xin,et al.Empirical study of design-oriented refactorings in open source projects.Journal of Frontiers of Computer Science and Technology,2017,11(9):1418-1428.

10.3778/j.issn.1673-9418.1609025

*The National Natural Science Foundation of China under Grant No.61370079(國家自然科學基金);the National Key Research and Development Program of China under Grant No.2016YFB1000801(國家重點研發計劃).

CNKI網絡優先出版: 2016-11-07, http://www.cnki.net/kcms/detail/11.5602.TP.20161107.1703.008.html

摘 要:軟件在演化過程中經常被修改,軟件結構往往會偏離原有的設計方向,軟件質量也會逐漸變差。不良設計造成的技術債務在后續開發過程中會帶來許多困難和阻礙,需要及時重構,改善原有代碼的不良設計。對常見的重構操作進行了簡單介紹和分類。在兩個開源項目上進行了經驗研究,關注兩個問題:(1)重構在開源項目中是否被廣泛應用,其中是否存在面向設計的重構;(2)是否存在沒有及時重構改善原有代碼的不良設計,導致后續開發遇到不必要的困難的情況,并且后續是否進行了重構。初步證明了重構在開源項目中的廣泛應用和重要性,以及面向設計的重構的重要作用。

猜你喜歡
設計研究
FMS與YBT相關性的實證研究
2020年國內翻譯研究述評
遼代千人邑研究述論
何為設計的守護之道?
現代裝飾(2020年7期)2020-07-27 01:27:42
《豐收的喜悅展示設計》
流行色(2020年1期)2020-04-28 11:16:38
視錯覺在平面設計中的應用與研究
科技傳播(2019年22期)2020-01-14 03:06:54
EMA伺服控制系統研究
瞞天過?!律O計萌到家
藝術啟蒙(2018年7期)2018-08-23 09:14:18
設計秀
海峽姐妹(2017年7期)2017-07-31 19:08:17
新版C-NCAP側面碰撞假人損傷研究
主站蜘蛛池模板: 国产jizzjizz视频| 中文字幕色站| 欧美成人区| 久久国产亚洲偷自| 久久人与动人物A级毛片| 免费观看成人久久网免费观看| 国产av色站网站| 她的性爱视频| 亚洲a免费| 波多野结衣国产精品| 亚洲欧美一区二区三区蜜芽| 欧美在线一二区| 国产流白浆视频| 黄色一级视频欧美| 国产黄色爱视频| 91精品国产自产在线观看| 无码粉嫩虎白一线天在线观看| 黄色网站不卡无码| 国产亚洲高清在线精品99| 国产无码精品在线播放| 中文字幕在线观看日本| 国产黑丝一区| 二级特黄绝大片免费视频大片| 中文字幕资源站| 五月婷婷伊人网| 在线视频一区二区三区不卡| 亚洲Av综合日韩精品久久久| 亚洲美女视频一区| 99精品视频在线观看免费播放| 在线观看亚洲天堂| 日本三级黄在线观看| 三级国产在线观看| 午夜精品久久久久久久2023| 99999久久久久久亚洲| 亚洲六月丁香六月婷婷蜜芽| 999福利激情视频 | 欧美怡红院视频一区二区三区| 久久久久久久久亚洲精品| 国产亚洲现在一区二区中文| 国产主播在线一区| 亚洲一区波多野结衣二区三区| 热re99久久精品国99热| 88国产经典欧美一区二区三区| 综合网久久| 国产在线观看91精品| 国产精品三区四区| 国产精品女主播| 黄片一区二区三区| 91破解版在线亚洲| 深爱婷婷激情网| 免费毛片网站在线观看| 欧美中文一区| 成人午夜久久| 免费A级毛片无码免费视频| 人妖无码第一页| 国产精品视频第一专区| 91小视频在线观看| 亚洲欧美一区二区三区麻豆| 久草视频中文| 亚洲综合婷婷激情| 五月婷婷伊人网| 国内精品自在自线视频香蕉| 欧美激情福利| 亚洲欧美成aⅴ人在线观看| 亚洲国产系列| 一级毛片基地| 国产欧美日韩另类| 激情综合网址| 夜精品a一区二区三区| 精品少妇三级亚洲| 亚洲成人黄色在线观看| 华人在线亚洲欧美精品| 91精品国产麻豆国产自产在线| 影音先锋亚洲无码| 99久久国产综合精品女同| 国产在线精彩视频二区| 国产高清国内精品福利| 久热精品免费| 人人爽人人爽人人片| 丁香婷婷激情综合激情| 亚洲日本韩在线观看| 国产一二三区视频|