亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        面向設(shè)計(jì)的開(kāi)源軟件項(xiàng)目重構(gòu)經(jīng)驗(yàn)研究*

        2017-09-18 00:28:53趙文耘
        計(jì)算機(jī)與生活 2017年9期
        關(guān)鍵詞:開(kāi)發(fā)人員對(duì)話框開(kāi)源

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

        1.復(fù)旦大學(xué) 軟件學(xué)院,上海 201203 2.復(fù)旦大學(xué) 上海數(shù)據(jù)科學(xué)重點(diǎn)實(shí)驗(yàn)室,上海 201203

        面向設(shè)計(jì)的開(kāi)源軟件項(xiàng)目重構(gòu)經(jīng)驗(yàn)研究*

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

        1.復(fù)旦大學(xué) 軟件學(xué)院,上海 201203 2.復(fù)旦大學(xué) 上海數(shù)據(jù)科學(xué)重點(diǎn)實(shí)驗(yàn)室,上海 201203

        技術(shù)債;軟件設(shè)計(jì);重構(gòu);開(kāi)源項(xiàng)目

        1 引言

        在現(xiàn)實(shí)世界中,軟件不是一成不變的。隨著時(shí)間的推移,軟件一直在不斷演化。演化的原因可能包括增加新需求,修改原有功能,刪除無(wú)用功能,修復(fù)軟件漏洞或者改善軟件性能等。代碼量在軟件演化過(guò)程中變得愈來(lái)愈龐大,代碼結(jié)構(gòu)也愈來(lái)愈復(fù)雜,偏離了最初的設(shè)計(jì)方向,軟件的質(zhì)量和可理解性也會(huì)降低。此時(shí)如果不及時(shí)對(duì)軟件進(jìn)行重構(gòu),會(huì)給后續(xù)開(kāi)發(fā)帶來(lái)許多困難和阻礙。

        重構(gòu)是在不改變軟件外部行為的條件下,對(duì)軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,提高軟件的可理解性,降低其修改成本[1]。重構(gòu)可以改善軟件的設(shè)計(jì),提高代碼的可理解性,幫助開(kāi)發(fā)人員定位bug位置,使程序員能夠更加快速地開(kāi)發(fā)軟件[1]。在實(shí)際軟件開(kāi)發(fā)過(guò)程中,重構(gòu)逐漸占有越來(lái)越重要的地位,特別是在敏捷開(kāi)發(fā)和極限編程實(shí)踐里。極限編程團(tuán)隊(duì)通過(guò)周期性的重構(gòu)來(lái)扭轉(zhuǎn)軟件退化,并循環(huán)持續(xù)進(jìn)行重構(gòu)[2]。

        項(xiàng)目開(kāi)發(fā)之初會(huì)對(duì)高層架構(gòu)進(jìn)行設(shè)計(jì),后續(xù)開(kāi)發(fā)中根據(jù)設(shè)計(jì)的架構(gòu)完成項(xiàng)目的編碼工作。一份好的設(shè)計(jì)可以讓開(kāi)發(fā)者輕松地完成工作,相反一份不好的設(shè)計(jì)會(huì)使開(kāi)發(fā)者在面對(duì)同樣的工作時(shí)付出更多的勞動(dòng)。在實(shí)際開(kāi)發(fā)過(guò)程中,即使有良好的設(shè)計(jì),但為了盡早交付軟件產(chǎn)品,開(kāi)發(fā)人員往往會(huì)犧牲代碼質(zhì)量,破壞原有的設(shè)計(jì)。這就是技術(shù)債,長(zhǎng)遠(yuǎn)的債務(wù)需要在維護(hù)階段花費(fèi)更多的人力去補(bǔ)償。

        重構(gòu)是否真的可以改善代碼質(zhì)量,重構(gòu)在實(shí)際軟件開(kāi)發(fā)過(guò)程中的地位如何。針對(duì)這兩個(gè)問(wèn)題,本文選擇兩個(gè)開(kāi)源項(xiàng)目進(jìn)行經(jīng)驗(yàn)研究,主要有兩個(gè)關(guān)注點(diǎn):(1)實(shí)際項(xiàng)目中重構(gòu)出現(xiàn)的頻率和類型,其中面向設(shè)計(jì)的重構(gòu)在所有重構(gòu)中是否是重要的一部分;(2)不好的設(shè)計(jì)是否真的對(duì)軟件開(kāi)發(fā)造成了困難和阻礙,這種情況在開(kāi)源項(xiàng)目中是否真實(shí)存在,如果對(duì)其進(jìn)行合理的重構(gòu),是否有利于后續(xù)的開(kāi)發(fā)。

        本文組織結(jié)構(gòu)如下:第2章簡(jiǎn)要概述本文的相關(guān)工作;第3章通過(guò)一個(gè)使用策略模式進(jìn)行重構(gòu)的例子證明重構(gòu)的重要性,繼而介紹重構(gòu)的相關(guān)概念;第4章描述研究的問(wèn)題,介紹選取的研究對(duì)象以及選取原因,并說(shuō)明數(shù)據(jù)收集方法;第5章根據(jù)收集到的數(shù)據(jù)回答研究問(wèn)題并得出結(jié)論;第6章對(duì)研究中的發(fā)現(xiàn)和不足之處進(jìn)行討論;第7章總結(jié)全文。

        2 相關(guān)工作

        下面從重構(gòu)和技術(shù)債兩部分介紹相關(guān)工作。重構(gòu)部分介紹目前學(xué)術(shù)界對(duì)重構(gòu)的相關(guān)研究;技術(shù)債部分描述了設(shè)計(jì)相關(guān)的技術(shù)債的研究工作,說(shuō)明了不良設(shè)計(jì)問(wèn)題對(duì)于軟件開(kāi)發(fā)和維護(hù)的阻礙。

        2.1 重構(gòu)

        眾多學(xué)者對(duì)重構(gòu)的時(shí)機(jī)和分類已經(jīng)進(jìn)行了研究。Fowler[1]的工作總結(jié)了22種代碼壞味道幫助定位重構(gòu)機(jī)會(huì),總結(jié)了一系列重構(gòu)類型,以及指導(dǎo)怎樣合理進(jìn)行重構(gòu)。Gamma等人[3]分類整理了共23種設(shè)計(jì)模式,幫助開(kāi)發(fā)者設(shè)計(jì)出更加靈活的、模塊化的、可復(fù)用的和易理解的軟件。Kerievsky[4]在前兩者的基礎(chǔ)上把重構(gòu)與模式結(jié)合起來(lái)進(jìn)行考慮,描述了模式導(dǎo)向的重構(gòu)。

        Mens等人[5]對(duì)目前為止軟件重構(gòu)技術(shù)進(jìn)行了總結(jié),對(duì)每個(gè)重構(gòu)階段的相關(guān)研究都進(jìn)行了介紹,并分析了目前研究出的技術(shù)和工具。Mens等人[6]指出未來(lái)重構(gòu)面臨的問(wèn)題是基本原理問(wèn)題和實(shí)踐問(wèn)題。

        代碼壞味道會(huì)阻礙軟件演化,開(kāi)發(fā)歷史中對(duì)代碼壞味道的修改明顯多于其他部分[7-8]。Munro[9]提出了一種通過(guò)使用度量值的集合自動(dòng)監(jiān)測(cè)代碼壞味道的方法。

        M?ntyl?[10]發(fā)現(xiàn)處于領(lǐng)導(dǎo)級(jí)別的工程師更關(guān)注于較高層次的代碼壞味道,而且在項(xiàng)目中經(jīng)驗(yàn)豐富的人員能發(fā)現(xiàn)更多的代碼壞味道;人工進(jìn)行的代碼壞味道甄別和現(xiàn)有的度量產(chǎn)生了沖突。Kataoka等人[11]設(shè)計(jì)了一款通過(guò)程序不變量來(lái)挑選出代碼壞味道并進(jìn)行重構(gòu)的工具。

        現(xiàn)有研究面向的重構(gòu)操作大都是簡(jiǎn)單的原子性操作,當(dāng)需要完成比較高級(jí)的復(fù)合型操作時(shí),仍舊需要人工進(jìn)行輔助。

        2.2 技術(shù)債

        技術(shù)債由Cunningham首次提出,指的是開(kāi)發(fā)團(tuán)隊(duì)在設(shè)計(jì)或架構(gòu)選型時(shí)從短期效應(yīng)的角度選擇了一個(gè)易于實(shí)現(xiàn)的方案,但從長(zhǎng)遠(yuǎn)來(lái)看,這種方案會(huì)帶來(lái)更消極的影響,亦即開(kāi)發(fā)團(tuán)隊(duì)所欠的債務(wù)[12]。

        在技術(shù)債相關(guān)信息不明確的時(shí)候,Guo等人[13]對(duì)技術(shù)債的問(wèn)題嚴(yán)重性,技術(shù)債是如何影響軟件項(xiàng)目和技術(shù)債影響軟件項(xiàng)目的哪些方面進(jìn)行了探索。Schmid[14]提出應(yīng)該用一系列近似值來(lái)模擬各個(gè)方面,然后慎重決定技術(shù)債。Tom等人[15]對(duì)技術(shù)債提出了一個(gè)完整的理論框架體系。

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

        3 案例介紹

        本章通過(guò)一個(gè)計(jì)算顧客購(gòu)物清單應(yīng)支付金額的案例,介紹重構(gòu)相關(guān)的基本知識(shí),展示結(jié)構(gòu)設(shè)計(jì)對(duì)于軟件演化的影響,以及利用重構(gòu)進(jìn)行結(jié)構(gòu)調(diào)整對(duì)于軟件后續(xù)開(kāi)發(fā)的益處。

        3.1 案例描述

        案例的大致結(jié)構(gòu)如圖1所示,圖中展示了一個(gè)在商場(chǎng)中付款時(shí),用來(lái)計(jì)算顧客購(gòu)買(mǎi)貨物應(yīng)支付金額的類Payment。

        Fig.1 Payment class structure圖1 Payment類結(jié)構(gòu)

        用戶分為3種:(1)有等級(jí)并可以使用積分的用戶;(2)有等級(jí)但不可以使用積分的用戶;(3)無(wú)等級(jí)的用戶。有等級(jí)的用戶可以享受對(duì)應(yīng)的等級(jí)打折優(yōu)惠,并且可以使用積分來(lái)抵消掉一部分的消費(fèi)金額。

        3.2 問(wèn)題分析和解決

        這個(gè)計(jì)算支付金額的案例存在設(shè)計(jì)缺陷。設(shè)計(jì)最大的缺點(diǎn)是當(dāng)對(duì)原有功能進(jìn)行擴(kuò)展時(shí)會(huì)遇到很多阻礙,比如需要根據(jù)顧客所選擇的支付方式提供一些不同的優(yōu)惠政策,這些優(yōu)惠有著不同的計(jì)算方式。如果采取圖1所示的設(shè)計(jì)方法,需要修改大量的分支代碼。這樣的設(shè)計(jì)會(huì)令后續(xù)的功能擴(kuò)展更加困難,當(dāng)出現(xiàn)復(fù)雜的邏輯判斷時(shí),往往需要進(jìn)行重構(gòu)來(lái)減少程序復(fù)雜度。

        面對(duì)圖1中所展示的結(jié)構(gòu),適用于使用策略模式進(jìn)行結(jié)構(gòu)上的改進(jìn)和優(yōu)化。應(yīng)用策略模式令客戶端的代碼與實(shí)際的算法分離,便于對(duì)原有算法進(jìn)行修改以及增加新算法等。在應(yīng)用策略模式后,調(diào)整后的設(shè)計(jì)結(jié)構(gòu)如圖2所示。

        此設(shè)計(jì)的優(yōu)點(diǎn)在于可以使計(jì)算模塊和客戶端分開(kāi),當(dāng)需要增加新的計(jì)算方式時(shí),可以直接在服務(wù)端進(jìn)行修改,客戶端可以很簡(jiǎn)單地通過(guò)調(diào)用新增的策略來(lái)實(shí)現(xiàn),對(duì)客戶端的修改量很小。例如需要根據(jù)顧客所選擇的支付方式提供一些不同的優(yōu)惠政策時(shí),所要進(jìn)行的修改只是去增加繼承自GetBillStrategy抽象類的一種新的計(jì)算方式策略類。重構(gòu)可以幫助開(kāi)發(fā)者改善代碼結(jié)構(gòu),更加有益于新功能的添加和后續(xù)的維護(hù)工作。面對(duì)同樣增加新功能的需求,優(yōu)化后代碼所需要進(jìn)行的修改量遠(yuǎn)遠(yuǎn)少于未進(jìn)行優(yōu)化的代碼。

        接下來(lái),對(duì)研究中出現(xiàn)的重構(gòu)進(jìn)行介紹。

        Fig.2 Payment class structure after using strategy mode圖2 應(yīng)用策略模式后的Payment類結(jié)構(gòu)

        3.3 重構(gòu)操作介紹

        如前文曾經(jīng)介紹過(guò)的,現(xiàn)有重構(gòu)的命名都是基于文獻(xiàn)[1]進(jìn)行的,本文按照重構(gòu)是否涉及軟件設(shè)計(jì)和難易程度將重構(gòu)分為3類:不涉及設(shè)計(jì)的重構(gòu)、涉及設(shè)計(jì)的簡(jiǎn)單重構(gòu)和基于設(shè)計(jì)模式的重構(gòu)。

        這里所說(shuō)的是否涉及到設(shè)計(jì),采用如下判定方式:所應(yīng)用的重構(gòu)方式是否改變了原有的類結(jié)構(gòu),包括類在包中的位置、類與類之間的依賴關(guān)系等,這樣的變化可以通過(guò)類圖直觀地展現(xiàn)。

        3.3.1 不涉及設(shè)計(jì)的重構(gòu)

        提煉函數(shù),替換算法,分解/合并條件式,重新命名函數(shù)/重新命名屬性等重構(gòu)方法是在實(shí)際研究過(guò)程中觀察到的不涉及軟件設(shè)計(jì)的重構(gòu)。不涉及設(shè)計(jì)的重構(gòu)的操作比較單一,多數(shù)是一些簡(jiǎn)化和移動(dòng)操作。

        3.3.2 涉及設(shè)計(jì)的簡(jiǎn)單重構(gòu)

        搬移函數(shù),提煉類,用多態(tài)替換條件式,函數(shù)上移/下移,提煉父類等重構(gòu)方式都涉及到對(duì)設(shè)計(jì)的優(yōu)化與改進(jìn),其中一些實(shí)現(xiàn)是由比較簡(jiǎn)單的重構(gòu)所構(gòu)成。

        3.3.3 基于設(shè)計(jì)模式的重構(gòu)

        設(shè)計(jì)模式是經(jīng)過(guò)分類的反復(fù)使用的代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié),可以方便進(jìn)行后續(xù)的代碼復(fù)用。設(shè)計(jì)模式的應(yīng)用會(huì)伴隨著新的輔助類的添加或者是對(duì)現(xiàn)有類的結(jié)構(gòu)調(diào)整,是一種比較高級(jí)的重構(gòu)方式。

        4 研究方案

        本章對(duì)研究的整體過(guò)程進(jìn)行介紹:首先說(shuō)明研究所關(guān)注的兩個(gè)問(wèn)題;其次介紹選取的研究對(duì)象,并解釋選取研究對(duì)象的原因;最后介紹數(shù)據(jù)收集的方法。

        4.1 研究問(wèn)題

        本研究的目的在于發(fā)現(xiàn)重構(gòu)在現(xiàn)實(shí)項(xiàng)目中是否有廣泛的應(yīng)用,研究面向軟件設(shè)計(jì)的重構(gòu)在所有重構(gòu)中的重要性,以及分析重構(gòu)是否會(huì)改善軟件設(shè)計(jì)。在對(duì)開(kāi)源項(xiàng)目的研究中,主要關(guān)注以下兩個(gè)研究問(wèn)題。

        問(wèn)題1重構(gòu)在現(xiàn)實(shí)項(xiàng)目中是否有很多應(yīng)用,其中是否出現(xiàn)了面向設(shè)計(jì)的重構(gòu)。

        研究問(wèn)題1的主要目的是研究在開(kāi)源項(xiàng)目中開(kāi)發(fā)人員對(duì)重構(gòu)的重視程度,并且在其中發(fā)現(xiàn)開(kāi)發(fā)人員對(duì)面向軟件設(shè)計(jì)的重構(gòu)的關(guān)注度。在版本歷史中,研究開(kāi)發(fā)人員是否發(fā)現(xiàn)重構(gòu)機(jī)會(huì)然后進(jìn)行重構(gòu),可以了解重構(gòu)在開(kāi)源項(xiàng)目中是否被認(rèn)可和應(yīng)用,其中面向軟件設(shè)計(jì)的重構(gòu)的比例可以顯示出這類重構(gòu)是否是重要的一部分。

        問(wèn)題2在現(xiàn)實(shí)項(xiàng)目中,是否存在由于未進(jìn)行重構(gòu)改善不良設(shè)計(jì),導(dǎo)致后續(xù)開(kāi)發(fā)過(guò)程中遇到了不必要的障礙的情況,以及后續(xù)是否意識(shí)到并進(jìn)行重構(gòu)。

        研究問(wèn)題2的主要目的是研究面向設(shè)計(jì)的重構(gòu)的影響,關(guān)注點(diǎn)在于開(kāi)源項(xiàng)目中是否真實(shí)存在這樣面向設(shè)計(jì)的重構(gòu)。當(dāng)存在這樣的重構(gòu)機(jī)會(huì)時(shí),觀察在后續(xù)沒(méi)有進(jìn)行重構(gòu)的這一段開(kāi)發(fā)過(guò)程中,開(kāi)發(fā)人員是否因?yàn)檫@樣的不良設(shè)計(jì)遇到了不必要的困難。如果在開(kāi)源項(xiàng)目中找到了面向設(shè)計(jì)的重構(gòu),通過(guò)研究重構(gòu)前的開(kāi)發(fā)階段,考慮面向設(shè)計(jì)的重構(gòu)是否可以解決這些阻礙。

        4.2 研究對(duì)象介紹

        本文選取jEdit和Jabref兩個(gè)開(kāi)源項(xiàng)目作為研究對(duì)象。選擇這兩個(gè)開(kāi)源項(xiàng)目的原因有以下兩點(diǎn):(1)這兩個(gè)開(kāi)源項(xiàng)目使用Java語(yǔ)言編寫(xiě),Java語(yǔ)言是一種面向?qū)ο蟮母呒?jí)編程語(yǔ)言,出現(xiàn)重構(gòu)機(jī)會(huì)的可能性更高;(2)項(xiàng)目規(guī)模較小,更利于理解代碼結(jié)構(gòu)和內(nèi)部邏輯。

        4.2.1 jEdit

        jEdit是一款比較成熟的開(kāi)源程序員文本編輯器,由Slava Pestov在1998年進(jìn)行主要內(nèi)核的開(kāi)發(fā),目前內(nèi)核大致穩(wěn)定沒(méi)有繼續(xù)修改,但仍有很多開(kāi)發(fā)者在制作和更新相應(yīng)插件。

        4.2.2 Jabref

        Jabref是一個(gè)用Java語(yǔ)言編寫(xiě)的支持多平臺(tái)的文獻(xiàn)推送和管理工具,2005年開(kāi)始開(kāi)發(fā),到目前為止仍在持續(xù)開(kāi)發(fā)和更新。

        4.3 數(shù)據(jù)收集

        在對(duì)這兩個(gè)開(kāi)源項(xiàng)目的研究中,分別選擇了3個(gè)版本間的所有提交作為研究對(duì)象。jEdit選擇了jedit-4-3-pre16至jedit-4-3-pre17和jedit-4-3-pre17至jedit-4-3-pre18兩個(gè)階段;Jabref選擇了v2.11至v2.11.1和v2.11.1至v3.0兩個(gè)階段。在選擇了研究目標(biāo)后,對(duì)數(shù)據(jù)進(jìn)行了預(yù)處理,最后采用人工閱讀的方式收集所需數(shù)據(jù)。

        4.3.1 數(shù)據(jù)預(yù)處理

        由于開(kāi)源項(xiàng)目的提交次數(shù)多,修改的文件之間的關(guān)系復(fù)雜,人工閱讀所有提交歷史并統(tǒng)計(jì)數(shù)據(jù)是不現(xiàn)實(shí)的。針對(duì)這個(gè)問(wèn)題,對(duì)這兩個(gè)項(xiàng)目的各個(gè)階段設(shè)計(jì)了對(duì)應(yīng)的數(shù)據(jù)庫(kù)表結(jié)構(gòu)來(lái)儲(chǔ)存相關(guān)信息,方便查詢和統(tǒng)計(jì)。在數(shù)據(jù)庫(kù)上進(jìn)行的數(shù)據(jù)統(tǒng)計(jì)需要基于人工閱讀的經(jīng)驗(yàn)。

        4.3.2 人工閱讀

        人工閱讀開(kāi)源項(xiàng)目的提交歷史是本文經(jīng)驗(yàn)研究的主要方法,在人工閱讀過(guò)程中主要關(guān)注兩個(gè)研究問(wèn)題。

        問(wèn)題1主要面向的對(duì)象是開(kāi)發(fā)項(xiàng)目過(guò)程中開(kāi)發(fā)人員實(shí)際做出的重構(gòu)操作,并要關(guān)注其中涉及到軟件設(shè)計(jì)的部分。對(duì)于這個(gè)研究問(wèn)題,在人工閱讀過(guò)程中需要注意觀察提交日志帶有refactoring關(guān)鍵字的提交。同時(shí)需要通過(guò)閱讀源碼發(fā)現(xiàn)未標(biāo)明的重構(gòu),結(jié)合提交信息和具體的修改內(nèi)容人工判斷每次提交的意圖,了解是否應(yīng)用了重構(gòu)操作,以及是否存在面向設(shè)計(jì)的重構(gòu)。

        問(wèn)題2主要研究的是開(kāi)發(fā)的某段過(guò)程中是否存在不好的設(shè)計(jì),使后續(xù)開(kāi)發(fā)遇到了不必要的困難。這個(gè)問(wèn)題采用兩種思路進(jìn)行研究:第一種思路是在閱讀前對(duì)項(xiàng)目的各個(gè)模塊進(jìn)行大致的理解,了解程序的運(yùn)行流程和互相之間的調(diào)用處理關(guān)系,在這個(gè)基礎(chǔ)上尋找不好的設(shè)計(jì),并追蹤這個(gè)設(shè)計(jì)對(duì)于后續(xù)開(kāi)發(fā)的不良影響。第二種思路是先尋找到開(kāi)發(fā)人員已經(jīng)進(jìn)行過(guò)的面向設(shè)計(jì)的重構(gòu),在這次重構(gòu)的提交基礎(chǔ)上回溯檢查此次提交前的提交,從而發(fā)現(xiàn)沒(méi)有進(jìn)行改善設(shè)計(jì)的重構(gòu)前,開(kāi)發(fā)過(guò)程中是否遇到了阻礙。

        5 結(jié)果分析

        本章對(duì)研究結(jié)果進(jìn)行分析。數(shù)據(jù)來(lái)源于兩個(gè)開(kāi)源項(xiàng)目的4個(gè)開(kāi)發(fā)階段,在后文中表示如下: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 問(wèn)題1

        所有提交在數(shù)據(jù)庫(kù)統(tǒng)計(jì)中發(fā)現(xiàn),有一部分不包含java文件,修改的是用于記錄的log文檔、配置文件等,可以通過(guò)文件類型進(jìn)行排除。在排除了無(wú)關(guān)的提交后,pre1617、pre1718、v11to111和v111to3的提交次數(shù)為230次、134次、58次和278次。

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

        jEdit的開(kāi)發(fā)時(shí)間要遠(yuǎn)遠(yuǎn)早于Jabref,所研究的jEdit開(kāi)發(fā)階段的時(shí)間在2008年11月至2009年11月,Jabref所研究的開(kāi)發(fā)階段在2015年11月,這證明了重構(gòu)的重要性正一步步被認(rèn)可,提交日志中注明“refactoring”或“restructure”關(guān)鍵字的提交逐漸變多。

        pre1617、pre1718、v11to111和v111to3所包含的重構(gòu)次數(shù)分別為31次、8次、19次和43次。在jEdit中平均有10.71%的提交是關(guān)于重構(gòu)的,在Jabref中平均有18.45%的提交是關(guān)于重構(gòu)的,這些數(shù)據(jù)說(shuō)明了重構(gòu)在開(kāi)發(fā)中的重要性,開(kāi)發(fā)人員進(jìn)行了不少?zèng)]有意識(shí)到的重構(gòu)。

        開(kāi)發(fā)人員進(jìn)行過(guò)的重構(gòu)主要有8種類型,分別是搬移函數(shù)、提煉類、方法上移、改變參數(shù)、搬移值域、重命名函數(shù)或?qū)傩?、替換算法、提煉方法和自封裝值域。所列舉的前5種重構(gòu)會(huì)涉及到軟件設(shè)計(jì)的調(diào)整,因?yàn)檫@些重構(gòu)會(huì)更改類之間的調(diào)用關(guān)系或?qū)哟谓Y(jié)構(gòu)。

        各個(gè)種類的重構(gòu)操作在pre1617、pre1718、v11to111和v111to3中的比例如圖3所示,明顯看到重命名和搬移函數(shù)重構(gòu)操作在各個(gè)研究階段分布較多。重命名和搬移函數(shù)重構(gòu)的經(jīng)常出現(xiàn)表明,在開(kāi)發(fā)過(guò)程中對(duì)類的職責(zé)劃分不清晰。重命名重構(gòu)以下的部分表示面向軟件設(shè)計(jì)的重構(gòu)操作,面向軟件設(shè)計(jì)的重構(gòu)在每個(gè)階段所占比例大約在50%左右,pre1718因?yàn)榘溯^少的重構(gòu)操作(8次),所以被排除在外。從這個(gè)比例可以看出,面向設(shè)計(jì)的重構(gòu)操作在所有重構(gòu)中占有較高比例。

        Fig.3 Refactoring classification ratio圖3 重構(gòu)分類比例

        研究中觀察到的面向設(shè)計(jì)的重構(gòu)操作包含搬移函數(shù)、提煉類、方法上移、改變參數(shù)和搬移值域。這些重構(gòu)有一個(gè)共同點(diǎn):在重構(gòu)中涉及到的修改的類大多只有兩個(gè)。這說(shuō)明目前觀察到的涉及軟件設(shè)計(jì)的重構(gòu)是比較簡(jiǎn)單的重構(gòu),只是兩個(gè)類之間的結(jié)構(gòu)的分配,沒(méi)有比較復(fù)雜的涉及多個(gè)類結(jié)構(gòu)的重構(gòu)出現(xiàn)。

        重構(gòu)在實(shí)際項(xiàng)目中有著重要的應(yīng)用,項(xiàng)目中對(duì)其關(guān)注度也越來(lái)越高。但是目前開(kāi)發(fā)人員對(duì)于重構(gòu)的認(rèn)知度偏低,對(duì)實(shí)際上是重構(gòu)操作的提交很少進(jìn)行注明。開(kāi)發(fā)人員對(duì)于重命名等簡(jiǎn)單重構(gòu)已經(jīng)有普遍認(rèn)知,基本能夠主動(dòng)標(biāo)識(shí)。面向軟件設(shè)計(jì)的重構(gòu)在重構(gòu)中出現(xiàn)頻率較高,主要是在兩個(gè)類之間進(jìn)行相關(guān)的函數(shù)和屬性搬移,調(diào)整類的層次結(jié)構(gòu)等簡(jiǎn)單重構(gòu),但沒(méi)有應(yīng)用設(shè)計(jì)模式的復(fù)雜重構(gòu)出現(xiàn)。

        5.2 問(wèn)題2

        由于未及時(shí)重構(gòu),不合理的設(shè)計(jì)對(duì)后續(xù)開(kāi)發(fā)造成了阻礙的情況是存在的,但是其中的大部分沒(méi)有被合理地重構(gòu)或者處理方式不合適。下面通過(guò)兩個(gè)最典型的例子進(jìn)行分析研究,并展示合理的重構(gòu)對(duì)后續(xù)開(kāi)發(fā)的積極影響。其中5.2.1小節(jié)中的例子被開(kāi)發(fā)人員識(shí)別出重構(gòu)機(jī)會(huì)并進(jìn)行了重構(gòu),5.2.2小節(jié)中的例子沒(méi)有進(jìn)行重構(gòu)。

        5.2.1 保存對(duì)話框尺寸的設(shè)計(jì)

        Jabref的圖形化界面模塊中存在一個(gè)包gui,專門(mén)用來(lái)保存與界面相關(guān)的對(duì)象,其中一部分對(duì)象用來(lái)表示對(duì)話框。有一個(gè)對(duì)話框類DuplicateResolverDialog實(shí)現(xiàn)了用于保存位置和大小信息的方法savePosition。

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

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

        Fig.4 Irrelevant dialog structure圖4 無(wú)關(guān)聯(lián)的對(duì)話框結(jié)構(gòu)

        id為c47fe58的提交中發(fā)現(xiàn)了這個(gè)問(wèn)題,對(duì)于結(jié)構(gòu)的調(diào)整是提取savePosition方法為GUIGlobals的靜態(tài)方法,并通過(guò)重命名函數(shù)和增加參數(shù)的重構(gòu)修改為storeDialogSize方法。與此同時(shí),設(shè)置大小和位置的代碼塊提取出來(lái)成為GUIGlobals的靜態(tài)方法set-DialogSize,結(jié)構(gòu)如圖5所示。在id為c582705的提交中對(duì)這一部分又進(jìn)行了重構(gòu),提煉單獨(dú)的Position-Window類來(lái)維護(hù)這兩個(gè)靜態(tài)方法用以調(diào)用。

        Fig.5 Dialog structure after refactoring in project圖5 項(xiàng)目中重構(gòu)后對(duì)話框結(jié)構(gòu)

        這樣的設(shè)計(jì)改進(jìn)是可以消除冗余代碼和減少后期維護(hù)難度的,但不是最好的面向?qū)ο蟮慕鉀Q辦法。提取方法作為靜態(tài)方法的處理方式破壞了面向?qū)ο蟮睦砟?,很難利用多態(tài)處理相關(guān)問(wèn)題。在研究中發(fā)現(xiàn)有十幾次類似的通過(guò)將方法提取到通用類中改為靜態(tài)方法的方式處理相似問(wèn)題,這樣的處理方式并沒(méi)有對(duì)設(shè)計(jì)進(jìn)行修改,開(kāi)發(fā)人員考慮到修改后的測(cè)試成本和軟件的正確性問(wèn)題等多方面原因,選擇最簡(jiǎn)單的增加靜態(tài)功能的方式進(jìn)行處理,沒(méi)有從根本上改善設(shè)計(jì)問(wèn)題。

        設(shè)置和存儲(chǔ)對(duì)話框大小位置信息的功能在邏輯上與對(duì)話框類聯(lián)系緊密,應(yīng)該作為對(duì)話框類的方法實(shí)現(xiàn)。一個(gè)較好的改進(jìn)方案是為需要實(shí)現(xiàn)該功能的對(duì)話框?qū)崿F(xiàn)統(tǒng)一的父類,其中storeDialogSize和set-DialogSize方法,實(shí)現(xiàn)該功能的類繼承自這個(gè)父類獲取該方法的實(shí)現(xiàn),重構(gòu)后結(jié)構(gòu)如圖6。這樣不僅可以消除冗余代碼,而且當(dāng)特別的子類需要有特別的邏輯修改時(shí)還可以通過(guò)覆寫(xiě)的方式修改,改善了代碼的可維護(hù)性和可擴(kuò)展性。

        Fig.6 Dialog structure after reasonably refactoring圖6 合理重構(gòu)后對(duì)話框結(jié)構(gòu)

        5.2.2 模式選擇的設(shè)計(jì)

        Jabref在搜索部分需要選擇不同的搜索模式而使用不同的策略進(jìn)行搜索,設(shè)計(jì)的方式是使用一個(gè)枚舉類型的SearchMode保存相關(guān)內(nèi)容,在SearchBar通過(guò)對(duì)應(yīng)的RadioButton來(lái)進(jìn)行切換選擇策略。Jabref沒(méi)有進(jìn)行很好的設(shè)計(jì),導(dǎo)致有大量switch和if…else…語(yǔ)句出現(xiàn)在方法中,主要表現(xiàn)在initSearchModeMenu、getSearchModeMenuItem、getSearchMode、focus和 on-SearchTextChanged這5個(gè)方法中。

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

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

        這個(gè)設(shè)計(jì)問(wèn)題可以通過(guò)應(yīng)用狀態(tài)模式解決。后文對(duì)簡(jiǎn)化后3種模式的實(shí)現(xiàn)進(jìn)行優(yōu)化分析,設(shè)計(jì)結(jié)構(gòu)調(diào)整如圖9。

        Fig.9 SearchBar structure after refactoring圖9 重構(gòu)后SearchBar結(jié)構(gòu)

        在沒(méi)有應(yīng)用設(shè)計(jì)模式的重構(gòu)前,實(shí)現(xiàn)對(duì)搜索模式的增刪修改時(shí),需要對(duì)SearchBar類中涉及到模式類型判斷的方法進(jìn)行大量修改,同時(shí)需要修改用于維護(hù)信息的SearchMode類。如果能及時(shí)應(yīng)用本文所調(diào)整的結(jié)構(gòu),增刪模式的操作變得極為簡(jiǎn)單。當(dāng)需要變更模式類型時(shí),只需要增加SearchMode對(duì)應(yīng)的模式實(shí)現(xiàn),并修改SearchBar的初始化方法實(shí)現(xiàn)對(duì)應(yīng)按鈕的添加,再在Globals存儲(chǔ)的模式數(shù)組中添加名稱字符串,就可以完成模式的增刪,不需要在項(xiàng)目中修改大量的方法,同時(shí)可以減少大量判斷語(yǔ)句的使用,提高代碼性能,代碼結(jié)構(gòu)也更加清晰易懂。

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

        6 討論

        本章介紹在研究過(guò)程中產(chǎn)生的思考以及研究中存在的不足。

        6.1 不良設(shè)計(jì)的出現(xiàn)與原因

        不良設(shè)計(jì)是導(dǎo)致代碼質(zhì)量下降的重要原因之一,阻礙開(kāi)發(fā)人員對(duì)軟件的開(kāi)發(fā)和維護(hù)。及時(shí)利用重構(gòu)改善不良設(shè)計(jì)是理想的處理方法,可以降低不良設(shè)計(jì)對(duì)后續(xù)開(kāi)發(fā)造成的危害。研究中發(fā)現(xiàn)不良設(shè)計(jì)的出現(xiàn)與原因可以總結(jié)為3種情況:

        (1)在軟件設(shè)計(jì)階段產(chǎn)生的不良設(shè)計(jì)。軟件架構(gòu)師不可能設(shè)計(jì)出絕對(duì)正確的軟件設(shè)計(jì),這種不良設(shè)計(jì)的出現(xiàn)是無(wú)可避免的。

        (2)由于技術(shù)債產(chǎn)生的不良設(shè)計(jì)。由于人力、時(shí)間和資源等因素的限制,開(kāi)發(fā)人員無(wú)法在要求的短期時(shí)間內(nèi)交付可展示的工作成果。為了及時(shí)交付工作成果,開(kāi)發(fā)人員往往選擇舍棄部分設(shè)計(jì)以在短期內(nèi)完成工作,也就是軟件工程領(lǐng)域的技術(shù)債問(wèn)題。面向設(shè)計(jì)的技術(shù)債屬于開(kāi)發(fā)人員不得不因?yàn)楝F(xiàn)實(shí)因素做出讓步的一種決策。

        (3)在開(kāi)發(fā)過(guò)程中產(chǎn)生的不良設(shè)計(jì)。軟件開(kāi)發(fā)是一個(gè)漫長(zhǎng)的過(guò)程,期間會(huì)出現(xiàn)無(wú)數(shù)次的功能增加與變更。功能的增加與變更會(huì)改變?cè)械念惤Y(jié)構(gòu),這會(huì)暴露出目前設(shè)計(jì)的問(wèn)題。這種問(wèn)題在設(shè)計(jì)之初可能不是一個(gè)不良設(shè)計(jì),在后續(xù)的修改過(guò)程中才變成了不良設(shè)計(jì)。

        考慮5.2.1小節(jié)的例子,最初只有DuplicateResolver-Dialog這一個(gè)對(duì)話框類實(shí)現(xiàn)了保存對(duì)話框大小的功能,僅在該類中維護(hù)相關(guān)方法是合理的。如果在設(shè)計(jì)之初設(shè)計(jì)成繼承父類方法的方式,會(huì)使其他對(duì)話框類出現(xiàn)不必要的方法,父類在整個(gè)結(jié)構(gòu)中顯得多余。當(dāng)增加MergeEntryDialog類和MergeEntry-DOIDialog類后,才發(fā)現(xiàn)原來(lái)設(shè)計(jì)的不足之處,需要消除冗余代碼。

        了解不良設(shè)計(jì)的出現(xiàn)階段和原因能夠幫助對(duì)不良設(shè)計(jì)進(jìn)行追蹤和記錄,有利于為后續(xù)維護(hù)和修改提供有益信息。

        (1)和(2)中產(chǎn)生的不良設(shè)計(jì)可以通過(guò)審查和記錄的方式發(fā)現(xiàn)問(wèn)題所在,但(3)中產(chǎn)生的不良設(shè)計(jì)需要在開(kāi)發(fā)中定期進(jìn)行重構(gòu)才可以解決。

        6.2 重構(gòu)的價(jià)值和面臨的問(wèn)題

        經(jīng)過(guò)研究,開(kāi)源項(xiàng)目歷史中已經(jīng)存在重構(gòu)相關(guān)的提交,面向設(shè)計(jì)的重構(gòu)在所有發(fā)現(xiàn)的重構(gòu)中占有接近一半的數(shù)量,是重構(gòu)中重要的一部分。面向設(shè)計(jì)的重構(gòu)可以提高可理解度,也能夠減少冗余的代碼,降低代碼的維護(hù)難度。如果在開(kāi)發(fā)過(guò)程中自覺(jué)地進(jìn)行重構(gòu),可以為以后的開(kāi)發(fā)降低難度,提高效率。

        但重構(gòu)仍然面臨一些問(wèn)題:首先是對(duì)重構(gòu)的認(rèn)知,目前開(kāi)發(fā)人員對(duì)于重構(gòu)普遍只處于聽(tīng)說(shuō)過(guò)的階段,并不了解重構(gòu)的具體內(nèi)容,這使重構(gòu)難以系統(tǒng)地進(jìn)行;其次是重構(gòu)的效益,重構(gòu)后代碼的優(yōu)點(diǎn)更多體現(xiàn)在后續(xù)的開(kāi)發(fā)過(guò)程中,這種未來(lái)效益很難得到重視;面向設(shè)計(jì)一類的復(fù)雜重構(gòu)不僅修改一個(gè)類,常常涉及到幾個(gè)類的變動(dòng),其間難免會(huì)出現(xiàn)漏洞,這樣的修改成本和測(cè)試成本是開(kāi)發(fā)人員不愿意承擔(dān)的,因此開(kāi)發(fā)人員更偏向于改動(dòng)單一的類來(lái)完成需求,不會(huì)自覺(jué)地進(jìn)行較為復(fù)雜的重構(gòu)。

        開(kāi)發(fā)人員對(duì)重構(gòu)的不理解,管理人員對(duì)重構(gòu)的輕視和重構(gòu)成本過(guò)高,是無(wú)法進(jìn)行重構(gòu)的主要原因。通過(guò)自動(dòng)判定應(yīng)當(dāng)應(yīng)用重構(gòu)的位置和自動(dòng)應(yīng)用重構(gòu)后,重構(gòu)的價(jià)值可以更好地體現(xiàn),降低重構(gòu)難度和成本,重構(gòu)才能真正應(yīng)用到每個(gè)開(kāi)發(fā)過(guò)程中。

        6.3 研究不足

        研究可能會(huì)因?yàn)橐韵聨讉€(gè)因素導(dǎo)致研究結(jié)果不準(zhǔn)確,主要包括對(duì)面向設(shè)計(jì)的重構(gòu)的識(shí)別,研究對(duì)象的選擇和開(kāi)發(fā)階段的識(shí)別3個(gè)因素。

        6.3.1 重構(gòu)分類準(zhǔn)確性

        對(duì)于現(xiàn)有的重構(gòu)操作,本文按照重構(gòu)是否改變了軟件設(shè)計(jì)將其分為3類,主要判斷依據(jù)是重構(gòu)是否改變了軟件類之間的依賴關(guān)系,使用類圖展示可以清晰地辨別出這種變化,但是有一部分重構(gòu)無(wú)法準(zhǔn)確判斷是否改變了設(shè)計(jì)。

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

        6.3.2 研究對(duì)象選擇

        研究中選取了兩個(gè)項(xiàng)目,jEdit開(kāi)發(fā)時(shí)間比Jabref更早。這里可能出現(xiàn)的問(wèn)題是研究選取的對(duì)象太少,在兩個(gè)開(kāi)源項(xiàng)目間的統(tǒng)計(jì)和比較可能不具有普遍性,但是在研究項(xiàng)目中發(fā)現(xiàn)的實(shí)例確實(shí)可以證明不良設(shè)計(jì)對(duì)于軟件開(kāi)發(fā)的不良影響,而且驗(yàn)證了重構(gòu)對(duì)于改善設(shè)計(jì)的重要作用。

        6.3.3 版本選擇問(wèn)題

        本文在每個(gè)開(kāi)源項(xiàng)目的兩個(gè)開(kāi)發(fā)階段通過(guò)統(tǒng)計(jì)和閱讀源碼的方式進(jìn)行研究,開(kāi)發(fā)階段的選取是隨機(jī)的。這樣選取開(kāi)發(fā)階段可能會(huì)存在問(wèn)題,jEdit是保持內(nèi)核基本不變的開(kāi)源項(xiàng)目,選取的階段可能設(shè)計(jì)已經(jīng)基本定型,暴露出的問(wèn)題可能偏少,而處于不斷開(kāi)發(fā)過(guò)程的Jabref項(xiàng)目中暴露設(shè)計(jì)問(wèn)題的可能性更高。同時(shí)隨機(jī)化挑選也有一定優(yōu)勢(shì),隨機(jī)化挑選開(kāi)發(fā)階段可以排除由于挑選開(kāi)發(fā)活動(dòng)頻繁的階段造成的結(jié)論特殊性。

        7 結(jié)束語(yǔ)

        軟件在現(xiàn)實(shí)世界中不是一成不變的,隨著時(shí)間的推移一直在不斷進(jìn)行演化。為了解決各種原因造成的代碼設(shè)計(jì)問(wèn)題,需要在開(kāi)發(fā)過(guò)程中不斷進(jìn)行重構(gòu)改善代碼質(zhì)量。

        在對(duì)現(xiàn)有重構(gòu)類型和應(yīng)用場(chǎng)景已經(jīng)有一定理解的基礎(chǔ)上,本文提出了兩個(gè)研究問(wèn)題進(jìn)行探索。研究中選取兩個(gè)開(kāi)源項(xiàng)目作為研究對(duì)象,在每個(gè)研究對(duì)象上隨機(jī)選取兩個(gè)版本間的開(kāi)發(fā)歷史作為觀察,通過(guò)數(shù)據(jù)預(yù)處理后人工閱讀的方式收集開(kāi)源項(xiàng)目中的實(shí)際例證和數(shù)據(jù)進(jìn)行問(wèn)題研究。

        研究證明重構(gòu)是開(kāi)發(fā)過(guò)程中重要的一部分,在研究的兩個(gè)開(kāi)源項(xiàng)目的提交歷史中分別占有10.71%和18.45%的比例。雖然重構(gòu)在項(xiàng)目中應(yīng)用很多,但是開(kāi)發(fā)人員在應(yīng)用重構(gòu)的過(guò)程中往往沒(méi)有意識(shí)到所做的操作是重構(gòu),沒(méi)有在提交日志中說(shuō)明,提交日志中指明修改是重構(gòu)的提交只占實(shí)際重構(gòu)中極小的一部分。提交日志中指明本次修改是重構(gòu)的提交中,主要的重構(gòu)類型是重命名,這說(shuō)明開(kāi)發(fā)人員對(duì)于重構(gòu)操作的類型和定義的了解只處于最初級(jí)的階段。面向設(shè)計(jì)的重構(gòu)在所有重構(gòu)中占據(jù)將近1/2的數(shù)量,是重構(gòu)的一個(gè)重要方面。開(kāi)發(fā)人員在開(kāi)發(fā)中識(shí)別出并進(jìn)行重構(gòu)的面向設(shè)計(jì)重構(gòu)只涉及兩個(gè)類之間的變動(dòng),操作過(guò)于簡(jiǎn)單。

        研究過(guò)程中發(fā)現(xiàn)了這樣的情況,由于未進(jìn)行合理設(shè)計(jì),導(dǎo)致進(jìn)行功能擴(kuò)展的過(guò)程中遇到了不必要的障礙,極少有開(kāi)發(fā)人員意識(shí)到是設(shè)計(jì)問(wèn)題并進(jìn)行重構(gòu)調(diào)整。但是所進(jìn)行的重構(gòu)并沒(méi)有在根本上解決設(shè)計(jì)問(wèn)題,有時(shí)反而會(huì)導(dǎo)致其他設(shè)計(jì)問(wèn)題的出現(xiàn)。研究通過(guò)提出合理的解決辦法,將合理重構(gòu)方式與開(kāi)發(fā)人員實(shí)際重構(gòu)進(jìn)行對(duì)比,體現(xiàn)出應(yīng)用合理重構(gòu)對(duì)于提高代碼質(zhì)量的重要性,很大程度上改善了代碼的可維護(hù)性。軟件設(shè)計(jì)在開(kāi)發(fā)過(guò)程中具有指導(dǎo)性意義,在演化過(guò)程中軟件設(shè)計(jì)的退化問(wèn)題和技術(shù)債的管理問(wèn)題往往需要應(yīng)用重構(gòu)去解決。

        未來(lái)的研究需要找到合適的評(píng)價(jià)軟件設(shè)計(jì)質(zhì)量的度量,從而指導(dǎo)在何時(shí)何處應(yīng)用何種重構(gòu)改善代碼設(shè)計(jì),沒(méi)有指導(dǎo)的盲目重構(gòu)是沒(méi)有意義的。目前沒(méi)有足夠的工具幫助開(kāi)發(fā)人員管理面向設(shè)計(jì)的技術(shù)債問(wèn)題,在未來(lái)對(duì)這些方面需要進(jìn)一步的研究。

        [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—),男,遼寧凌源人,復(fù)旦大學(xué)軟件工程實(shí)驗(yàn)室碩士研究生,主要研究領(lǐng)域?yàn)檐浖S護(hù)與演化。

        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—),男,江蘇泰州人,復(fù)旦大學(xué)軟件工程實(shí)驗(yàn)室碩士研究生,主要研究領(lǐng)域?yàn)檐浖S護(hù)與演化。

        彭鑫(1979—),男,湖北黃岡人,2006年于復(fù)旦大學(xué)計(jì)算機(jī)科學(xué)專業(yè)獲得博士學(xué)位,現(xiàn)為復(fù)旦大學(xué)教授,CCF高級(jí)會(huì)員,主要研究領(lǐng)域?yàn)樾枨蠊こ蹋赃m應(yīng)軟件,軟件產(chǎn)品線,軟件維護(hù),逆向工程。

        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年于復(fù)旦大學(xué)獲得碩士學(xué)位,現(xiàn)為復(fù)旦大學(xué)教授,CCF高級(jí)會(huì)員,主要研究領(lǐng)域?yàn)檐浖?fù)用,軟件產(chǎn)品線,軟件工程。

        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(國(guó)家自然科學(xué)基金);the National Key Research and Development Program of China under Grant No.2016YFB1000801(國(guó)家重點(diǎn)研發(fā)計(jì)劃).

        CNKI網(wǎng)絡(luò)優(yōu)先出版: 2016-11-07, http://www.cnki.net/kcms/detail/11.5602.TP.20161107.1703.008.html

        摘 要:軟件在演化過(guò)程中經(jīng)常被修改,軟件結(jié)構(gòu)往往會(huì)偏離原有的設(shè)計(jì)方向,軟件質(zhì)量也會(huì)逐漸變差。不良設(shè)計(jì)造成的技術(shù)債務(wù)在后續(xù)開(kāi)發(fā)過(guò)程中會(huì)帶來(lái)許多困難和阻礙,需要及時(shí)重構(gòu),改善原有代碼的不良設(shè)計(jì)。對(duì)常見(jiàn)的重構(gòu)操作進(jìn)行了簡(jiǎn)單介紹和分類。在兩個(gè)開(kāi)源項(xiàng)目上進(jìn)行了經(jīng)驗(yàn)研究,關(guān)注兩個(gè)問(wèn)題:(1)重構(gòu)在開(kāi)源項(xiàng)目中是否被廣泛應(yīng)用,其中是否存在面向設(shè)計(jì)的重構(gòu);(2)是否存在沒(méi)有及時(shí)重構(gòu)改善原有代碼的不良設(shè)計(jì),導(dǎo)致后續(xù)開(kāi)發(fā)遇到不必要的困難的情況,并且后續(xù)是否進(jìn)行了重構(gòu)。初步證明了重構(gòu)在開(kāi)源項(xiàng)目中的廣泛應(yīng)用和重要性,以及面向設(shè)計(jì)的重構(gòu)的重要作用。

        猜你喜歡
        開(kāi)發(fā)人員對(duì)話框開(kāi)源
        正?;謴?fù)虛擬機(jī)
        五毛錢(qián)能買(mǎi)多少頭牛
        Semtech發(fā)布LoRa Basics 以加速物聯(lián)網(wǎng)應(yīng)用
        Bootlace Worms’Secret etc.
        大家說(shuō):開(kāi)源、人工智能及創(chuàng)新
        開(kāi)源中國(guó)開(kāi)源世界高峰論壇圓桌會(huì)議縱論開(kāi)源與互聯(lián)網(wǎng)+創(chuàng)新2.0
        開(kāi)源計(jì)算機(jī)輔助翻譯工具研究
        讓W(xué)indows 10進(jìn)入開(kāi)發(fā)者模式
        電腦迷(2015年12期)2015-04-29 23:22:51
        后悔了?教你隱藏開(kāi)發(fā)人員選項(xiàng)
        快速抓取對(duì)話框中的完整信息
        電腦迷(2012年22期)2012-04-29 20:30:54
        婷婷色中文字幕综合在线| 国产人妻高清国产拍精品| 国产自拍视频在线观看网站| 精品国产品香蕉在线| 天天爽夜夜爽人人爽| 久久超碰97人人做人人爱 | 秋霞日韩一区二区三区在线观看| 性色av无码一区二区三区人妻| 亚洲综合色丁香婷婷六月图片| 免费网站国产| 国产精品每日更新在线观看| 久久国产精品男人的天堂av| 国产av一区二区内射| 蜜桃久久综合一区二区| 亚洲日本精品国产一区二区三区| 亚洲av无码偷拍在线观看| 无码人妻精品一区二区三区不卡| 乱子真实露脸刺激对白| 精品午夜一区二区三区久久| 毛片av在线尤物一区二区| 国产自拍三级黄片视频| 精品高清免费国产在线| 成人欧美一区二区三区在线| 精品久久久久久无码人妻热| 岛国成人在线| 亚洲色四在线视频观看| 尤物成av人片在线观看| 日韩av一区二区三区高清| 亚洲youwu永久无码精品| 日本中文字幕一区二区高清在线 | 欧美高清视频手机在在线| 狠狠躁夜夜躁人人躁婷婷视频| 欧美gv在线观看| 91福利国产在线观看网站| 国内人妖一区二区在线播放| 亚洲综合中文字幕日韩| www婷婷av久久久影片| 亚洲美女又黄又爽在线观看| 亚洲综合一| 久久精品国产亚洲av热东京热| 麻豆69视频在线观看|