• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

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

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

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

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

    面向設(shè)計(jì)的開源軟件項(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);開源項(xiàng)目

    1 引言

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

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

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

    重構(gòu)是否真的可以改善代碼質(zhì)量,重構(gòu)在實(shí)際軟件開發(fā)過程中的地位如何。針對這兩個(gè)問題,本文選擇兩個(gè)開源項(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ì)是否真的對軟件開發(fā)造成了困難和阻礙,這種情況在開源項(xiàng)目中是否真實(shí)存在,如果對其進(jìn)行合理的重構(gòu),是否有利于后續(xù)的開發(fā)。

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

    2 相關(guān)工作

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

    2.1 重構(gòu)

    眾多學(xué)者對重構(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ì)模式,幫助開發(fā)者設(shè)計(jì)出更加靈活的、模塊化的、可復(fù)用的和易理解的軟件。Kerievsky[4]在前兩者的基礎(chǔ)上把重構(gòu)與模式結(jié)合起來進(jìn)行考慮,描述了模式導(dǎo)向的重構(gòu)。

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

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

    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ì)了一款通過程序不變量來挑選出代碼壞味道并進(jìn)行重構(gòu)的工具。

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

    2.2 技術(shù)債

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

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

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

    3 案例介紹

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

    3.1 案例描述

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

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

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

    3.2 問題分析和解決

    這個(gè)計(jì)算支付金額的案例存在設(shè)計(jì)缺陷。設(shè)計(jì)最大的缺點(diǎn)是當(dāng)對原有功能進(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)來減少程序復(fù)雜度。

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

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

    接下來,對研究中出現(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)介紹過的,現(xiàn)有重構(gòu)的命名都是基于文獻(xiàn)[1]進(jìn)行的,本文按照重構(gòu)是否涉及軟件設(shè)計(jì)和難易程度將重構(gòu)分為3類:不涉及設(shè)計(jì)的重構(gòu)、涉及設(shè)計(jì)的簡單重構(gòu)和基于設(shè)計(jì)模式的重構(gòu)。

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

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

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

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

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

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

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

    4 研究方案

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

    4.1 研究問題

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

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

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

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

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

    4.2 研究對象介紹

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

    4.2.1 jEdit

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

    4.2.2 Jabref

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

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

    在對這兩個(gè)開源項(xiàng)目的研究中,分別選擇了3個(gè)版本間的所有提交作為研究對象。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)后,對數(shù)據(jù)進(jìn)行了預(yù)處理,最后采用人工閱讀的方式收集所需數(shù)據(jù)。

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

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

    4.3.2 人工閱讀

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

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

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

    5 結(jié)果分析

    本章對研究結(jié)果進(jìn)行分析。數(shù)據(jù)來源于兩個(gè)開源項(xiàng)目的4個(gè)開發(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 問題1

    所有提交在數(shù)據(jù)庫統(tǒng)計(jì)中發(fā)現(xiàn),有一部分不包含java文件,修改的是用于記錄的log文檔、配置文件等,可以通過文件類型進(jìn)行排除。在排除了無關(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)的提交(排除了對測試用例重構(gòu)的提交)。但在后續(xù)的人工閱讀階段發(fā)現(xiàn),重構(gòu)操作遠(yuǎn)不止搜索到的8次提交,這一情況說明現(xiàn)在開發(fā)人員對于重構(gòu)操作的認(rèn)識(shí)不夠,但是開發(fā)人員實(shí)際上進(jìn)行了一部分自身沒有意識(shí)到是重構(gòu)的操作。例如:一個(gè)搬移getBoolean方法的重構(gòu)被開發(fā)人員描述為“New method StandardUtilities.getBoolean()that will convert an object into a Boolean”,只提到了新方法的添加,沒有體現(xiàn)該方法移動(dòng)到StandardUtilities類中。兩個(gè)項(xiàng)目中標(biāo)明為重構(gòu)的共8次提交中有2次是提煉函數(shù)重構(gòu),其余6次是重命名重構(gòu),這些都是簡單的重構(gòu)類型,并且這些重構(gòu)大多只涉及一個(gè)類的修改。說明開發(fā)人員對于部分簡單重構(gòu)是有一定的理解的,或者說開發(fā)人員更認(rèn)可同一個(gè)類中進(jìn)行的重構(gòu)。

    jEdit的開發(fā)時(shí)間要遠(yuǎn)遠(yuǎn)早于Jabref,所研究的jEdit開發(fā)階段的時(shí)間在2008年11月至2009年11月,Jabref所研究的開發(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ù)說明了重構(gòu)在開發(fā)中的重要性,開發(fā)人員進(jìn)行了不少?zèng)]有意識(shí)到的重構(gòu)。

    開發(fā)人員進(jìn)行過的重構(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)表明,在開發(fā)過程中對類的職責(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è)。這說明目前觀察到的涉及軟件設(shè)計(jì)的重構(gòu)是比較簡單的重構(gòu),只是兩個(gè)類之間的結(jié)構(gòu)的分配,沒有比較復(fù)雜的涉及多個(gè)類結(jié)構(gòu)的重構(gòu)出現(xiàn)。

    重構(gòu)在實(shí)際項(xiàng)目中有著重要的應(yīng)用,項(xiàng)目中對其關(guān)注度也越來越高。但是目前開發(fā)人員對于重構(gòu)的認(rèn)知度偏低,對實(shí)際上是重構(gòu)操作的提交很少進(jìn)行注明。開發(fā)人員對于重命名等簡單重構(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)等簡單重構(gòu),但沒有應(yīng)用設(shè)計(jì)模式的復(fù)雜重構(gòu)出現(xiàn)。

    5.2 問題2

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

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

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

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

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

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

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

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

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

    設(shè)置和存儲(chǔ)對話框大小位置信息的功能在邏輯上與對話框類聯(lián)系緊密,應(yīng)該作為對話框類的方法實(shí)現(xiàn)。一個(gè)較好的改進(jìn)方案是為需要實(shí)現(xiàn)該功能的對話框?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í)還可以通過覆寫的方式修改,改善了代碼的可維護(hù)性和可擴(kuò)展性。

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

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

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

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

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

    這個(gè)設(shè)計(jì)問題可以通過應(yīng)用狀態(tài)模式解決。后文對簡化后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)

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

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

    6 討論

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

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

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

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

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

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

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

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

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

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

    經(jīng)過研究,開源項(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ù)難度。如果在開發(fā)過程中自覺地進(jìn)行重構(gòu),可以為以后的開發(fā)降低難度,提高效率。

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

    開發(fā)人員對重構(gòu)的不理解,管理人員對重構(gòu)的輕視和重構(gòu)成本過高,是無法進(jìn)行重構(gòu)的主要原因。通過自動(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è)開發(fā)過程中。

    6.3 研究不足

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

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

    對于現(xiàn)有的重構(gòu)操作,本文按照重構(gòu)是否改變了軟件設(shè)計(jì)將其分為3類,主要判斷依據(jù)是重構(gòu)是否改變了軟件類之間的依賴關(guān)系,使用類圖展示可以清晰地辨別出這種變化,但是有一部分重構(gòu)無法準(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 研究對象選擇

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

    6.3.3 版本選擇問題

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

    7 結(jié)束語

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

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

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

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

    未來的研究需要找到合適的評(píng)價(jià)軟件設(shè)計(jì)質(zhì)量的度量,從而指導(dǎo)在何時(shí)何處應(yīng)用何種重構(gòu)改善代碼設(shè)計(jì),沒有指導(dǎo)的盲目重構(gòu)是沒有意義的。目前沒有足夠的工具幫助開發(fā)人員管理面向設(shè)計(jì)的技術(shù)債問題,在未來對這些方面需要進(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)樾枨蠊こ?,自適應(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(國家自然科學(xué)基金);the National Key Research and Development Program of China under Grant No.2016YFB1000801(國家重點(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

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

    猜你喜歡
    開發(fā)人員對話框開源
    正?;謴?fù)虛擬機(jī)
    五毛錢能買多少頭牛
    Semtech發(fā)布LoRa Basics 以加速物聯(lián)網(wǎng)應(yīng)用
    Bootlace Worms’Secret etc.
    大家說:開源、人工智能及創(chuàng)新
    開源中國開源世界高峰論壇圓桌會(huì)議縱論開源與互聯(lián)網(wǎng)+創(chuàng)新2.0
    開源計(jì)算機(jī)輔助翻譯工具研究
    讓W(xué)indows 10進(jìn)入開發(fā)者模式
    電腦迷(2015年12期)2015-04-29 23:22:51
    后悔了?教你隱藏開發(fā)人員選項(xiàng)
    電腦愛好者(2015年6期)2015-04-03 01:20:56
    快速抓取對話框中的完整信息
    電腦迷(2012年22期)2012-04-29 20:30:54
    国产99白浆流出| 真人一进一出gif抽搐免费| 欧美色欧美亚洲另类二区| 精品国产乱子伦一区二区三区| 亚洲av五月六月丁香网| av欧美777| 一个人免费在线观看的高清视频| 欧美日韩一级在线毛片| 观看免费一级毛片| 亚洲欧美精品综合一区二区三区| 日韩欧美一区二区三区在线观看| 亚洲av第一区精品v没综合| 亚洲成人久久爱视频| 国产av一区在线观看免费| 99国产精品一区二区三区| 国产精品久久久久久亚洲av鲁大| 丰满人妻一区二区三区视频av | a在线观看视频网站| 人妻久久中文字幕网| 好看av亚洲va欧美ⅴa在| 欧美一区二区精品小视频在线| 精品乱码久久久久久99久播| 禁无遮挡网站| 一级作爱视频免费观看| 真实男女啪啪啪动态图| 中文亚洲av片在线观看爽| 国产主播在线观看一区二区| 搡老妇女老女人老熟妇| 精品午夜福利视频在线观看一区| 日韩国内少妇激情av| 欧美+亚洲+日韩+国产| 亚洲精品色激情综合| 亚洲精华国产精华精| 精品日产1卡2卡| 一个人看视频在线观看www免费 | 国产精品一区二区三区四区久久| 欧美成狂野欧美在线观看| 亚洲欧洲精品一区二区精品久久久| 国产毛片a区久久久久| 在线视频色国产色| 亚洲aⅴ乱码一区二区在线播放| 国产精品亚洲av一区麻豆| 在线国产一区二区在线| 欧美日本亚洲视频在线播放| 18禁美女被吸乳视频| 日本黄色片子视频| 久久精品国产综合久久久| 精品电影一区二区在线| 国产一区在线观看成人免费| 久久天堂一区二区三区四区| 美女午夜性视频免费| avwww免费| 免费电影在线观看免费观看| 亚洲成人中文字幕在线播放| 村上凉子中文字幕在线| 国产成人系列免费观看| 最近视频中文字幕2019在线8| 亚洲人与动物交配视频| 亚洲无线观看免费| 无遮挡黄片免费观看| 极品教师在线免费播放| 欧美极品一区二区三区四区| 麻豆成人av在线观看| 精品国产美女av久久久久小说| 狠狠狠狠99中文字幕| 婷婷丁香在线五月| 欧美日韩综合久久久久久 | 97超级碰碰碰精品色视频在线观看| 国产av麻豆久久久久久久| 每晚都被弄得嗷嗷叫到高潮| 亚洲av日韩精品久久久久久密| 欧美色视频一区免费| 怎么达到女性高潮| 久久人人精品亚洲av| 国产精品女同一区二区软件 | 欧美在线黄色| 性色av乱码一区二区三区2| www国产在线视频色| 亚洲自偷自拍图片 自拍| 国产男靠女视频免费网站| 亚洲性夜色夜夜综合| 欧美色欧美亚洲另类二区| 亚洲中文日韩欧美视频| 欧美在线黄色| 国产亚洲精品久久久com| 国产在线精品亚洲第一网站| 日韩精品青青久久久久久| 90打野战视频偷拍视频| 国产成人欧美在线观看| 麻豆成人av在线观看| 美女黄网站色视频| 国产精品美女特级片免费视频播放器 | 午夜福利在线观看免费完整高清在 | 精品不卡国产一区二区三区| 黄色成人免费大全| 又紧又爽又黄一区二区| 757午夜福利合集在线观看| 香蕉久久夜色| 神马国产精品三级电影在线观看| 制服丝袜大香蕉在线| 亚洲精品456在线播放app | 精品久久久久久久末码| 精品国产乱子伦一区二区三区| 国产爱豆传媒在线观看| 在线观看美女被高潮喷水网站 | 狠狠狠狠99中文字幕| 亚洲avbb在线观看| 国产一区二区三区视频了| 日本精品一区二区三区蜜桃| 免费在线观看成人毛片| 免费无遮挡裸体视频| 亚洲激情在线av| 亚洲欧美日韩高清专用| 欧美日韩国产亚洲二区| 国产不卡一卡二| 最近最新免费中文字幕在线| 看免费av毛片| 日韩欧美精品v在线| 啪啪无遮挡十八禁网站| 日日夜夜操网爽| 男人舔奶头视频| 国产精品av久久久久免费| 免费看日本二区| 白带黄色成豆腐渣| 国产av不卡久久| 亚洲欧美激情综合另类| 国产精品亚洲一级av第二区| 欧美日韩中文字幕国产精品一区二区三区| 久久这里只有精品19| 久久久久免费精品人妻一区二区| 一级a爱片免费观看的视频| 久久久久久久精品吃奶| 久久人妻av系列| 国产高清视频在线播放一区| 在线观看美女被高潮喷水网站 | 啪啪无遮挡十八禁网站| 美女被艹到高潮喷水动态| 伊人久久大香线蕉亚洲五| 欧美日韩中文字幕国产精品一区二区三区| xxxwww97欧美| 免费av不卡在线播放| 国产亚洲精品一区二区www| 人人妻,人人澡人人爽秒播| 性色av乱码一区二区三区2| 成年女人毛片免费观看观看9| 啦啦啦观看免费观看视频高清| 国产成人av激情在线播放| 精品一区二区三区av网在线观看| 天天一区二区日本电影三级| 婷婷亚洲欧美| 国内精品美女久久久久久| 国产亚洲精品久久久久久毛片| 一进一出抽搐gif免费好疼| 国产精品久久久av美女十八| 欧美日韩中文字幕国产精品一区二区三区| a在线观看视频网站| 法律面前人人平等表现在哪些方面| 搡老熟女国产l中国老女人| 两个人的视频大全免费| 国产精品av视频在线免费观看| 久久中文字幕一级| 一级作爱视频免费观看| 国产高清videossex| 特级一级黄色大片| 国产乱人视频| 国产成人精品无人区| 午夜久久久久精精品| 老汉色∧v一级毛片| 中文字幕熟女人妻在线| 中文字幕最新亚洲高清| 国产男靠女视频免费网站| 亚洲国产精品成人综合色| 国产综合懂色| 国产精品久久久av美女十八| 99riav亚洲国产免费| 亚洲av中文字字幕乱码综合| 国产成人系列免费观看| 这个男人来自地球电影免费观看| 国产亚洲精品av在线| 草草在线视频免费看| 美女cb高潮喷水在线观看 | 色吧在线观看| 一二三四社区在线视频社区8| 在线永久观看黄色视频| 午夜福利18| 悠悠久久av| 一个人看视频在线观看www免费 | 亚洲人成电影免费在线| 国产精品女同一区二区软件 | 热99在线观看视频| 国产av不卡久久| 天天躁日日操中文字幕| 99热这里只有精品一区 | 亚洲成人久久性| 美女免费视频网站| АⅤ资源中文在线天堂| 又大又爽又粗| 首页视频小说图片口味搜索| 久久热在线av| h日本视频在线播放| 欧美日韩黄片免| 成人国产一区最新在线观看| 国产又色又爽无遮挡免费看| 精品国产亚洲在线| 网址你懂的国产日韩在线| 99国产精品一区二区三区| 色综合婷婷激情| 亚洲av五月六月丁香网| 午夜视频精品福利| 免费av毛片视频| 五月玫瑰六月丁香| av中文乱码字幕在线| 欧美三级亚洲精品| h日本视频在线播放| 99久久99久久久精品蜜桃| 国产 一区 欧美 日韩| 最新在线观看一区二区三区| 最近在线观看免费完整版| www.www免费av| 成人性生交大片免费视频hd| 久久热在线av| 日韩中文字幕欧美一区二区| 一区福利在线观看| 久久精品综合一区二区三区| 欧美成狂野欧美在线观看| 精品久久蜜臀av无| av黄色大香蕉| 在线观看舔阴道视频| 一个人看的www免费观看视频| 欧美一区二区精品小视频在线| 色哟哟哟哟哟哟| 国产高潮美女av| 欧美又色又爽又黄视频| 欧美又色又爽又黄视频| 男女床上黄色一级片免费看| 国产黄色小视频在线观看| 免费搜索国产男女视频| 久久性视频一级片| 一进一出抽搐动态| 亚洲欧美精品综合久久99| 国产精品99久久久久久久久| 亚洲 欧美 日韩 在线 免费| 2021天堂中文幕一二区在线观| 国产黄a三级三级三级人| 亚洲人与动物交配视频| 亚洲av成人一区二区三| 国产精品久久久久久亚洲av鲁大| 久久久精品欧美日韩精品| 亚洲人成伊人成综合网2020| 99久久99久久久精品蜜桃| 2021天堂中文幕一二区在线观| 久久亚洲精品不卡| 男女视频在线观看网站免费| 亚洲第一电影网av| 岛国在线观看网站| 国产一区二区在线观看日韩 | 一本久久中文字幕| 国产精品1区2区在线观看.| 99国产综合亚洲精品| 黑人欧美特级aaaaaa片| 欧美午夜高清在线| 亚洲avbb在线观看| 国产真人三级小视频在线观看| 午夜激情欧美在线| 久久久久久九九精品二区国产| 男女视频在线观看网站免费| 久久精品国产综合久久久| 十八禁网站免费在线| 国产亚洲欧美98| 亚洲电影在线观看av| cao死你这个sao货| 熟妇人妻久久中文字幕3abv| 精品久久久久久久毛片微露脸| 欧美大码av| 国产不卡一卡二| 国产视频内射| 亚洲 国产 在线| 日韩高清综合在线| 免费无遮挡裸体视频| 欧美性猛交╳xxx乱大交人| 中文字幕久久专区| 亚洲国产欧洲综合997久久,| 男女那种视频在线观看| 久久精品国产清高在天天线| 亚洲第一电影网av| 18禁黄网站禁片免费观看直播| 熟女人妻精品中文字幕| 1000部很黄的大片| 成年人黄色毛片网站| 色老头精品视频在线观看| 视频区欧美日本亚洲| 国产综合懂色| 宅男免费午夜| 国产综合懂色| 色吧在线观看| 国产 一区 欧美 日韩| 一区福利在线观看| 久久精品国产99精品国产亚洲性色| 大型黄色视频在线免费观看| 操出白浆在线播放| av在线蜜桃| 一本久久中文字幕| 成人特级黄色片久久久久久久| а√天堂www在线а√下载| 俄罗斯特黄特色一大片| 亚洲成a人片在线一区二区| 国产高清视频在线播放一区| 给我免费播放毛片高清在线观看| 精品不卡国产一区二区三区| 亚洲精华国产精华精| 日本熟妇午夜| av在线天堂中文字幕| 99热精品在线国产| 亚洲国产欧洲综合997久久,| 精品国产乱子伦一区二区三区| 91麻豆精品激情在线观看国产| 精品午夜福利视频在线观看一区| 男女午夜视频在线观看| 国产精品美女特级片免费视频播放器 | 一二三四社区在线视频社区8| 级片在线观看| 91麻豆精品激情在线观看国产| 精品久久久久久成人av| 欧美在线黄色| 老司机午夜福利在线观看视频| 免费看a级黄色片| 99久久国产精品久久久| 亚洲专区中文字幕在线| tocl精华| 亚洲一区二区三区色噜噜| 男人的好看免费观看在线视频| 一二三四在线观看免费中文在| 国产黄色小视频在线观看| 搡老熟女国产l中国老女人| 亚洲熟妇熟女久久| 伦理电影免费视频| 在线永久观看黄色视频| 亚洲天堂国产精品一区在线| 精品乱码久久久久久99久播| 亚洲在线观看片| 在线免费观看的www视频| 久久伊人香网站| 男人舔女人的私密视频| 成人性生交大片免费视频hd| 日韩人妻高清精品专区| 女警被强在线播放| 欧美又色又爽又黄视频| 国产亚洲欧美98| 国产av在哪里看| 国内精品久久久久久久电影| 国产精品久久久久久亚洲av鲁大| e午夜精品久久久久久久| 大型黄色视频在线免费观看| 免费在线观看亚洲国产| 亚洲 国产 在线| 女警被强在线播放| 精品人妻1区二区| 久久久久性生活片| 又粗又爽又猛毛片免费看| 国产精品美女特级片免费视频播放器 | 99久久无色码亚洲精品果冻| 白带黄色成豆腐渣| 中国美女看黄片| 网址你懂的国产日韩在线| 啪啪无遮挡十八禁网站| 精品福利观看| www.www免费av| 中文亚洲av片在线观看爽| 18禁裸乳无遮挡免费网站照片| 又紧又爽又黄一区二区| 国产亚洲av嫩草精品影院| 在线观看66精品国产| 母亲3免费完整高清在线观看| 日本熟妇午夜| a级毛片在线看网站| 亚洲欧美精品综合一区二区三区| 一本久久中文字幕| 亚洲成人久久性| 欧美日韩一级在线毛片| 久久久久亚洲av毛片大全| 99久久国产精品久久久| 国产野战对白在线观看| 成熟少妇高潮喷水视频| 亚洲美女视频黄频| 伦理电影免费视频| 十八禁网站免费在线| 啦啦啦韩国在线观看视频| 变态另类丝袜制服| 亚洲成av人片在线播放无| 综合色av麻豆| 欧美乱码精品一区二区三区| 亚洲七黄色美女视频| 91九色精品人成在线观看| 香蕉丝袜av| 99国产精品一区二区三区| 两个人视频免费观看高清| 国产亚洲精品av在线| 舔av片在线| 小蜜桃在线观看免费完整版高清| 免费大片18禁| 超碰成人久久| 国产精品久久视频播放| 身体一侧抽搐| 中文字幕精品亚洲无线码一区| 亚洲精品一区av在线观看| 97超级碰碰碰精品色视频在线观看| 日本与韩国留学比较| 免费看日本二区| 午夜a级毛片| 国产高清videossex| 99热只有精品国产| 一级毛片高清免费大全| 久久久精品欧美日韩精品| 国产精品99久久久久久久久| 老鸭窝网址在线观看| h日本视频在线播放| 天天躁日日操中文字幕| 国产极品精品免费视频能看的| 99精品久久久久人妻精品| 午夜福利高清视频| 性欧美人与动物交配| 男女午夜视频在线观看| 国产激情久久老熟女| 欧美在线黄色| 最近最新中文字幕大全电影3| 在线免费观看的www视频| 可以在线观看毛片的网站| 嫩草影院精品99| 天天一区二区日本电影三级| 免费看十八禁软件| 久久久久久人人人人人| 亚洲人成电影免费在线| 天天躁狠狠躁夜夜躁狠狠躁| 国产成人啪精品午夜网站| 国产精品,欧美在线| av黄色大香蕉| 国产一区二区在线av高清观看| 午夜亚洲福利在线播放| 麻豆成人av在线观看| 后天国语完整版免费观看| 1000部很黄的大片| 最新在线观看一区二区三区| 久久精品aⅴ一区二区三区四区| 久久人妻av系列| 久久香蕉国产精品| 超碰成人久久| a在线观看视频网站| 国产伦精品一区二区三区视频9 | 搡老熟女国产l中国老女人| 欧美成人性av电影在线观看| h日本视频在线播放| 免费观看的影片在线观看| 999久久久国产精品视频| 国产69精品久久久久777片 | 看片在线看免费视频| 免费大片18禁| 小说图片视频综合网站| 女警被强在线播放| 亚洲成人中文字幕在线播放| 观看免费一级毛片| 精品久久久久久久毛片微露脸| 欧美精品啪啪一区二区三区| 青草久久国产| 此物有八面人人有两片| 精品99又大又爽又粗少妇毛片 | 亚洲av中文字字幕乱码综合| 日本a在线网址| av福利片在线观看| 操出白浆在线播放| 啦啦啦免费观看视频1| 中文在线观看免费www的网站| 19禁男女啪啪无遮挡网站| 亚洲专区字幕在线| 高清毛片免费观看视频网站| 亚洲专区中文字幕在线| 亚洲av电影不卡..在线观看| 天堂动漫精品| 又黄又粗又硬又大视频| 18美女黄网站色大片免费观看| 亚洲成人久久性| 女人被狂操c到高潮| 一进一出好大好爽视频| 国产成人精品久久二区二区免费| 亚洲国产精品成人综合色| 欧美三级亚洲精品| 国产亚洲欧美98| 日韩欧美一区二区三区在线观看| 99久久精品一区二区三区| 18禁美女被吸乳视频| 亚洲熟女毛片儿| 在线免费观看不下载黄p国产 | 亚洲 欧美一区二区三区| 免费观看人在逋| 国产精品亚洲一级av第二区| 久久这里只有精品19| 午夜a级毛片| 中文在线观看免费www的网站| 色综合站精品国产| 国语自产精品视频在线第100页| 麻豆国产av国片精品| 男女午夜视频在线观看| 午夜久久久久精精品| 久久久国产精品麻豆| 亚洲av五月六月丁香网| 欧美日韩一级在线毛片| 少妇丰满av| 日韩大尺度精品在线看网址| 18禁美女被吸乳视频| 亚洲电影在线观看av| xxxwww97欧美| 国产91精品成人一区二区三区| 看黄色毛片网站| 99久久无色码亚洲精品果冻| 国内少妇人妻偷人精品xxx网站 | 亚洲熟妇熟女久久| 亚洲国产精品合色在线| 一本一本综合久久| 搡老岳熟女国产| 国产成人av激情在线播放| 精品国产乱码久久久久久男人| 天天一区二区日本电影三级| 欧美色视频一区免费| 午夜免费成人在线视频| 欧美另类亚洲清纯唯美| 亚洲中文av在线| 精品福利观看| 美女 人体艺术 gogo| 男人舔女人下体高潮全视频| 日日摸夜夜添夜夜添小说| 日韩av在线大香蕉| 亚洲专区中文字幕在线| 国产精品 欧美亚洲| 亚洲无线在线观看| 国产黄片美女视频| 久99久视频精品免费| 国内揄拍国产精品人妻在线| 亚洲av中文字字幕乱码综合| 国产伦人伦偷精品视频| 我的老师免费观看完整版| 成人鲁丝片一二三区免费| 亚洲av美国av| 国产精品乱码一区二三区的特点| 麻豆成人午夜福利视频| 美女免费视频网站| 亚洲 欧美一区二区三区| 国产成人精品久久二区二区91| 日韩欧美 国产精品| 美女扒开内裤让男人捅视频| 他把我摸到了高潮在线观看| 99久久99久久久精品蜜桃| 18禁裸乳无遮挡免费网站照片| 2021天堂中文幕一二区在线观| 级片在线观看| 91av网站免费观看| 精品一区二区三区视频在线观看免费| 免费看日本二区| 亚洲精品美女久久av网站| 免费无遮挡裸体视频| 热99re8久久精品国产| 久久天堂一区二区三区四区| 国产午夜精品论理片| 青草久久国产| 午夜福利欧美成人| 少妇的逼水好多| 色精品久久人妻99蜜桃| 2021天堂中文幕一二区在线观| 日本一本二区三区精品| 日日干狠狠操夜夜爽| 18禁观看日本| 成人18禁在线播放| 国产精品女同一区二区软件 | 国产单亲对白刺激| 亚洲精品美女久久av网站| 国产乱人伦免费视频| 久久久久性生活片| 五月玫瑰六月丁香| 国产精品一区二区三区四区免费观看 | 最新在线观看一区二区三区| 国产精品一区二区三区四区久久| 国产精品国产高清国产av| 欧美日韩福利视频一区二区| 精品国产美女av久久久久小说| 一本综合久久免费| 别揉我奶头~嗯~啊~动态视频| 在线观看一区二区三区| netflix在线观看网站| 两性夫妻黄色片| avwww免费| 国产亚洲精品av在线| 香蕉国产在线看| av欧美777| 欧美乱码精品一区二区三区| 真人一进一出gif抽搐免费| 亚洲美女视频黄频| 欧美日韩国产亚洲二区| av女优亚洲男人天堂 | 日日夜夜操网爽| 中国美女看黄片| 国产成人系列免费观看| 麻豆一二三区av精品| 男插女下体视频免费在线播放| 亚洲欧美日韩无卡精品| 亚洲 欧美一区二区三区| 欧美成人一区二区免费高清观看 | 九色国产91popny在线| 最近最新中文字幕大全免费视频| www.自偷自拍.com| 丰满人妻熟妇乱又伦精品不卡| 欧美日韩乱码在线| 大型黄色视频在线免费观看| 真实男女啪啪啪动态图| 免费人成视频x8x8入口观看| 最好的美女福利视频网| 窝窝影院91人妻| 桃红色精品国产亚洲av|