





摘"要:在實(shí)際軟件開發(fā)中,開發(fā)人員通常會(huì)使用多個(gè)團(tuán)隊(duì)開發(fā)的程序來構(gòu)建軟件系統(tǒng)。然而,當(dāng)這些程序包存在不同的版本時(shí),將它們合并到一個(gè)完整的應(yīng)用程序中可能會(huì)引發(fā)沖突,導(dǎo)致程序錯(cuò)誤。提出了一種新的形式化模型——統(tǒng)一結(jié)構(gòu)作為包圖的形式語義,對(duì)程序代碼包合并提出了一種新的分析方法。該方法給出了三種包合并的策略,深入研究了將不同版本的代碼轉(zhuǎn)換成的包圖在合并過程中可能出現(xiàn)的沖突和不一致性問題,并提供了具體的解決方案。實(shí)驗(yàn)表明這個(gè)方法能確保合并后的代碼正確性,從而提高軟件開發(fā)的質(zhì)量和生產(chǎn)效率。
關(guān)鍵詞:代碼合并;"UML;"包圖;"形式化;"包合并;"合并沖突
中圖分類號(hào):TP311""""""文獻(xiàn)標(biāo)識(shí)碼:A
Formal"Methodsbased"Program"Code"Merging"Analysis
HE"Qing1,2,"JIANG"Jianmin1,2
(1."School"of"Software"Engineering,"Chengdu"University"of"Information"Technology,"Chengdu,"Sichuan"610225,"China;
2."Sichuan"Key"Laboratory"of"Software"Automatic"Generation"and"Intelligent"Service,"Chengdu,"Sichuan"610225,"China)
Abstract:"In"practical"software"development,"developers"often"use"programs"developed"by"multiple"teams"to"build"software"systems."However,"when"these"programs"exist"in"different"versions,"merging"them"into"a"complete"application"may"lead"to"conflicts,"resulting"in"program"errors."This"article"proposes"a"new"formal"modelunified"structure"as"package"diagram"formal"semantics,"for"program"code"package"merging,"presenting"a"novel"analysis"approach."This"method"offers"three"strategies"for"package"merging,"delving"into"potential"conflicts"and"inconsistencies"that"may"arise"when"merging"package"diagrams"representing"different"versions"of"code,"along"with"concrete"solutions."Experiments"demonstrate"that"this"method"can"ensure"the"correctness"of"merged"code,"thereby"enhancing"the"quality"and"productivity"of"software"development.
Key"words:code"merging;"UML;"package"diagram;"formalization;"package"merging;"merging"conflicts
在現(xiàn)代軟件工程中,隨著軟件系統(tǒng)的復(fù)雜性不斷增加,代碼合并成為一項(xiàng)關(guān)鍵任務(wù)。為了解決代碼合并帶來的挑戰(zhàn),研究人員和開發(fā)者們一直在尋找更好的方法和工具來簡化合并過程,以減少?zèng)_突和提高代碼集成的效率。有許多工具支持自動(dòng)合并程序或模型的兩個(gè)版本中兩個(gè)非沖突段的合并,但這些工具在解決程序或模型的沖突方面提供的幫助很少,沖突解決在很大程度上依賴于手動(dòng)干預(yù)。此外,開發(fā)人員可能對(duì)他正在合并的沖突塊缺乏足夠的了解,然后根據(jù)自己的經(jīng)驗(yàn)和對(duì)問題領(lǐng)域的一些知識(shí)進(jìn)行猜測。如果這些猜測是錯(cuò)誤的,可能會(huì)導(dǎo)致不必要的重復(fù)工作:識(shí)別合并問題,與團(tuán)隊(duì)成員協(xié)商以正確解決沖突,重新部署,重新回歸測試等。如果合并錯(cuò)誤且在部署之前未被識(shí)別,后果將更加災(zāi)難性。在這樣的背景下,使用嚴(yán)格的形式化方法和UML包合并對(duì)代碼合并進(jìn)行分析具有重要意義,然而,已有的工作并沒有使用過形式化方法對(duì)代碼合并進(jìn)行分析。
本文提出了一種新的模型——統(tǒng)一結(jié)構(gòu)模型作為UML包圖的形式語義,并且將形式化與包合并結(jié)合對(duì)代碼合并提出了一種新的分析方法?;谛问交P?,可以對(duì)包圖進(jìn)行形式化的分析、驗(yàn)證和推理。
UML包圖提供了對(duì)軟件架構(gòu)的可視化表示,能夠更好地描述系統(tǒng)的結(jié)構(gòu)和組織[1-3]。包圖也是一種面向?qū)ο蟪绦虼a的圖形表示方法,用于展示軟件系統(tǒng)中的包之間的關(guān)系和組織,從而幫助開發(fā)人員理解和管理代碼。在程序代碼中,類通常被組織在包內(nèi),這種組織結(jié)構(gòu)與UML中的包圖和類圖之間存在緊密的關(guān)系。
包合并(Package"Merging)是指將兩個(gè)或多個(gè)UMLnbsp;包合并為一個(gè)更大的包的過程。這種合并可以在系統(tǒng)設(shè)計(jì)和軟件開發(fā)過程中發(fā)揮重要作用,特別是當(dāng)存在多個(gè)子系統(tǒng)或模塊需要整合時(shí)[2]。通過將相關(guān)的包合并為一個(gè)較大的包,可以更好地表達(dá)系統(tǒng)的模塊化和分層設(shè)計(jì),減少不必要的復(fù)雜性。需要明確的是,合并后的包是一個(gè)邏輯上的組織結(jié)構(gòu),而不會(huì)生成新的包。當(dāng)一個(gè)包合并另一個(gè)包時(shí),包層面的元素是不變的。包合并實(shí)際上是對(duì)包內(nèi)的元素進(jìn)行合并。
本文使用統(tǒng)一結(jié)構(gòu)對(duì)UML包圖進(jìn)行了嚴(yán)格的形式化定義和描述,探討了三種合并策略的性質(zhì)以及不同的合并策略對(duì)合并結(jié)果的影響。然后通過詳細(xì)分析包合并中的沖突情況,提供了一個(gè)沖突解決框架,這個(gè)框架可以幫助軟件開發(fā)團(tuán)隊(duì)更好地識(shí)別和解決潛在的代碼合并沖突,提高代碼合并過程的效率和質(zhì)量。
1"相關(guān)工作
形式化方法已經(jīng)成功應(yīng)用于各種硬件設(shè)計(jì),特別是芯片的設(shè)計(jì)。各大硬件制造商都有一個(gè)非常強(qiáng)大的形式化方法團(tuán)隊(duì)為保障系統(tǒng)的可靠性提供技術(shù)支持,例如IBM、Intel、AMD等等。由于軟件系統(tǒng)的復(fù)雜性和不確定性遠(yuǎn)遠(yuǎn)超出硬件系統(tǒng),形式化方法在軟件開發(fā)中應(yīng)用程度并不高。但是在最近10多年中,隨著形式驗(yàn)證技術(shù)和工具的發(fā)展,特別是在程序驗(yàn)證中的成功應(yīng)用,形式化方法在處理軟件開發(fā)復(fù)雜性和提高軟件可靠性方面已顯示出無可取代的潛力[4]"。
Carré等介紹了對(duì)系統(tǒng)進(jìn)行形式化建模的方法[5],該論文使用包圖來表示系統(tǒng)示例,并采用了一種與本文所使用的形式化方法不同的描述方式對(duì)子模型的特殊形式,即子元模型,以及它們在模型空間結(jié)構(gòu)化中的特定角色進(jìn)行了分析。
在需要進(jìn)行模型合并的場景中,開發(fā)人員通常需要指定如何合并UML模型元素。Bischoff等[6]指出,可能有許多不同的合并設(shè)計(jì)模型的方式。然而,由于合并策略的日益多樣化以及UML表達(dá)特定合并語義甚至模型合并順序的局限性,指定如何合并輸入模型是一項(xiàng)特別具有挑戰(zhàn)性的任務(wù)。因此,開發(fā)人員最終無法表達(dá)如何合并輸入模型的各個(gè)部分。
迄今為止,UML缺乏幫助開發(fā)人員表達(dá)合并關(guān)系的結(jié)構(gòu)。在過去的研究中,發(fā)現(xiàn)了UML內(nèi)置的合并機(jī)制(即UML包合并)存在一系列模糊和缺失的規(guī)則[7-8]。盡管一些UML擴(kuò)展被提出來解決這些問題[9],但它們?nèi)晕茨転楹喜㈥P(guān)系提供具體的語義參數(shù)化。
盡管今天有許多不同的合并工具在使用,但眾所周知,在實(shí)踐中它們并不完美。因?yàn)樗鼈儫o法考慮到開發(fā)人員可能會(huì)進(jìn)行的每一種可能的并發(fā)變更,因此會(huì)出現(xiàn)無法自動(dòng)解決的并發(fā)變更之間的沖突,導(dǎo)致合并失敗[10]。開發(fā)人員必須介入,分析各自的變更及其引起的合并沖突,并手動(dòng)解決沖突。這是一項(xiàng)困難的任務(wù),開發(fā)人員希望盡量避免[11]。然而,據(jù)報(bào)道合并操作有10%~20%的失敗率[12],有些項(xiàng)目的失敗率甚至接近50%[13]。
2"形式化模型
本節(jié)給出用于包圖建模的形式化模型“統(tǒng)一結(jié)構(gòu)”,然后討論該模型的一些性質(zhì)。統(tǒng)一結(jié)構(gòu)(Unified"Structure)是我們研究團(tuán)隊(duì)在以前的形式化模型——依賴結(jié)構(gòu)(Dependency"Structure)[14-15]的基礎(chǔ)上開發(fā)出的新的基于結(jié)構(gòu)的形式化模型,統(tǒng)一結(jié)構(gòu)的表達(dá)能力和兼容性比依賴結(jié)構(gòu)更強(qiáng),目的是將UML模型進(jìn)行統(tǒng)一的形式化建模,從結(jié)構(gòu)的角度對(duì)UML模型進(jìn)行分析。
定義1:一個(gè)統(tǒng)一結(jié)構(gòu)模型是一個(gè)元組US=lt;ME,ω1,…,ωn,λm,λd,τ1,…,τmgt;,其中:
1)"ME,模型元素的有限集合。
2)"ME×ME,表示包含關(guān)系。
3)"i∈{1,…,n},ωiME×ME,表示依賴關(guān)系,它是一個(gè)非自反的偏序。
4)"λmME×ME,表示模型元素的約束條件。
5)"λdME×(∪ω1∪…∪ωn),表示依賴關(guān)系的約束條件。
6)"j∈{1,…,m},τjME,表示模型元素的類型集,如:e∈ME,τ∈{τ1,…,τm}:e∈τ。
對(duì)于所有的x,y∈ME,xωiy(i∈{1,…,n}),稱為一個(gè)依賴,解釋為x依賴于y(注意,i表示依賴關(guān)系的類型)。xy表示x包含在y中。如果xz,yz,它們被簡單地x,yz用來表示,表示x和y都包含在z中。對(duì)于所有w,v∈ME,符號(hào)v°w表示w不包含v。
元組τ1,…,τm是模型元素的分組結(jié)構(gòu),用來對(duì)模型元素進(jìn)行分類。例如在軟件開發(fā)過程中的模型元素可以分為需求、設(shè)計(jì)、實(shí)現(xiàn)、測試和編碼類型,相對(duì)應(yīng)的模型元素的類型集表示為需求集合、設(shè)計(jì)集合、實(shí)現(xiàn)集合、測試集合、編碼集合。用統(tǒng)一結(jié)構(gòu)表示為τrequirement,τdesign,τimplementation,τtesting,τcode。
根據(jù)定義1所定義的統(tǒng)一結(jié)構(gòu)將圖1表示為PD=lt;ME,,ωimport,λ,τPNamegt;,其中ME={A,B,C,D,E,F(xiàn)},={(B,A),(E,D),(C,D)},ωimport={(B,F(xiàn)),(B,C)},λ=,τPName={A,B,C,D,E,F(xiàn)}。這里解釋一下其中符號(hào)的含義:ME表示模型中所有元素的集合。如圖1中的A表示一個(gè)包;表示包含關(guān)系,C和D之間的連線是包含關(guān)系的另一種表示方式,表示D包含C;ωimport表示一個(gè)包使用或依賴另一個(gè)包中的元素,它包含泛化(generalization)/存?。╝ccess)關(guān)系。通過import關(guān)系,一個(gè)包可以引用另一個(gè)包中定義的類、接口、枚舉等元素,以便在自身內(nèi)部使用。例如(B,F(xiàn))∈ωimport表示B引用了F(B依賴于F);λ表示依賴關(guān)系的約束;τPName表示包的名稱。
3"包的合并
在生成所需的合并模型之前,開發(fā)人員需要比較輸入模型,以便確定它們之間的共同點(diǎn)和差異。匹配策略定義了比較和對(duì)比輸入模型的語義,識(shí)別它們的重疊部分和差異。在匹配輸入模型之后,下一步是將它們合并在一起。為此,可以使用合并策略。
基于匹配策略確定的輸入模型之間的重疊點(diǎn)以及它們的差異,合并策略定義了如何集成匹配部分。覆蓋合并、一般合并和聯(lián)合合并這三種合并策略被用于廣泛的合并場景[16],包括設(shè)計(jì)模型的演化、本體合并和概念模型合并。接下來,簡要介紹這三種策略,并假設(shè)Ma和Mb是輸入模型。
(1)覆蓋合并
當(dāng)包A使用覆蓋合并策略合并包B時(shí),有如下兩條規(guī)則:(1)若A與B存在匹配的元素,則只將A中的這些元素保留。(2)B中其他的元素直接復(fù)制到結(jié)果包中。覆蓋合并滿足冪等性和結(jié)合性,但是不滿足交換性。
(2)一般合并
當(dāng)包A使用一般合并策略合并包B時(shí),對(duì)于A和B中匹配的每一對(duì)元素,這些元素應(yīng)該進(jìn)行合并。合并的方式取決于元素的類型,即只有相同類型的模型元素可以進(jìn)行合并。A和B中不相同的元素保持不變,并直接插入到合并后的結(jié)果包中。一般合并滿足冪等性和結(jié)合性。但是,一般合并不滿足交換性。
(3)聯(lián)合合并
當(dāng)包A使用聯(lián)合合并策略合并包B時(shí),對(duì)于A和B中匹配的每一對(duì)元素,它們的名稱會(huì)被修改并插入到結(jié)果包中,以保留它們的標(biāo)識(shí)。這意味著在結(jié)果包中,它們以不同的標(biāo)識(shí)符或名稱共存。同時(shí),A和B中沒有匹配的部分將保持不變,并直接插入到結(jié)果包中。
聯(lián)合合并滿足交換性和結(jié)合性,不滿足冪等性。在聯(lián)合合并中,重復(fù)執(zhí)行合并操作會(huì)導(dǎo)致重復(fù)添加相同的元素,使得結(jié)果不再一致。這是因?yàn)樵诿看温?lián)合合并時(shí),對(duì)于每一對(duì)對(duì)應(yīng)的元素,它們的名稱會(huì)被修改并插入到合并后的包中,以保留它們的標(biāo)識(shí)。為了確保合并操作的正確性和一致性,在選擇合并策略時(shí),需要綜合考慮各種因素,并根據(jù)具體情況選擇適合的策略。
4"沖突和不一致
4.1"合并沖突
在UML中的包合并過程中,可能會(huì)出現(xiàn)一些沖突。如圖2所示,在Ma中,Order類的price屬性被定義為整數(shù)類型(int),而在Mb中Order類的price屬性為浮點(diǎn)數(shù)類型(float)。這兩個(gè)屬性類型的相互矛盾表示了一個(gè)需要開發(fā)人員解決的沖突。因此,開發(fā)人員需要回答一個(gè)關(guān)鍵問題:price屬性應(yīng)該是整數(shù)還是浮點(diǎn)數(shù)?
根據(jù)圖2所期望的合并結(jié)果Mab,正確的答案是Order類的price屬性應(yīng)該是浮點(diǎn)數(shù)類型(float),即Order.price"="float(Order.price表示Order中的屬性price)。然而,開發(fā)人員可能錯(cuò)誤地將其分配為整數(shù)類型。這將導(dǎo)致不一致,即合并輸出模型中的模型元素與開發(fā)人員所期望的合并模型之間存在分歧。
在包合并時(shí),沖突存在于兩個(gè)包之間的匹配的元素之間,如果沒有相同名稱的元素或沒有需要比較的內(nèi)容,就不會(huì)出現(xiàn)沖突。在包合并過程中,兩個(gè)包之間可能會(huì)出現(xiàn)以下幾種合并沖突類型:
(1)"數(shù)據(jù)類型沖突:當(dāng)合并兩個(gè)包時(shí),如果兩個(gè)包中具有相同名稱的屬性或方法返回不同的數(shù)據(jù)類型,就會(huì)發(fā)生沖突。例如,一個(gè)包中的類A的屬性b返回整數(shù)類型,而另一個(gè)包中的類A的屬性b返回浮點(diǎn)數(shù)類型。
(2)"依賴關(guān)系沖突:如果合并的包中存在相同元素之間的不一致依賴關(guān)系,也會(huì)導(dǎo)致沖突。
(3)"可見性沖突:當(dāng)合并兩個(gè)包時(shí),如果兩個(gè)包中的元素的可見性不一致,沖突可能發(fā)生??梢娦灾付嗽兀▽傩?、方法、類等)對(duì)其他模塊或類的可訪問性。例如,一個(gè)包中的屬性被定義為私有,而另一個(gè)包中的屬性被定義為公共。
(4)"類型抽象性沖突:當(dāng)合并兩個(gè)包時(shí),如果兩個(gè)包中的類的抽象性不一致,就會(huì)發(fā)生沖突。例如,一個(gè)包中將類定義為抽象類,而另一個(gè)包中將其定義為具體類。
(5)"命名沖突:如果兩個(gè)合并的包中存在相同名稱的元素(例如類、接口、枚舉等),則會(huì)出現(xiàn)名稱沖突。這可能導(dǎo)致模型的不一致,因?yàn)橄嗤Q的元素?zé)o法明確引用或使用。
統(tǒng)一結(jié)構(gòu)的設(shè)計(jì)原則允許在后續(xù)的變更中對(duì)系統(tǒng)進(jìn)行修改和擴(kuò)展。因此,在描述合并沖突時(shí),引入了抽象性和可見性這兩個(gè)集合,以滿足新的需求和設(shè)計(jì)要求。這項(xiàng)變更旨在提高系統(tǒng)的靈活性和可擴(kuò)展性,并確保以后的開發(fā)和維護(hù)能夠更好地滿足各種需求和變化。下面主要對(duì)部分類型的沖突進(jìn)行討論。
定義2:設(shè)PD=lt;ME,,ωimport,λ,τPNamegt;是一個(gè)包圖,MA,MB∈τPName,又設(shè)CD=lt;ME′,′,ωAssociaton′,ωUse′,ωAggegation′,ωComposition′,ωGeneralization′,ωRealization′,λ′m,λ′d,τCName′,τCProperty′,τCOperation′,τDataType′gt;和SD=lt;ME″,″,ωAssociaton″,ωUse″,ωAggegation″,ωComposition″,ωGeneralization″,ωRealization″,λ″m,λ″d,
τCName″,τCProperty″,τCOperation″,τDataType″gt;分別是MA和MB中的類圖。τvisibility表示元素的可見性,τvisibility={public,private,protect}。τAbs表示元素的抽象性,τAbs={true,1}。MA和MB兩個(gè)包合并時(shí)的沖突表示為Con(MA,MB)。
(1)"如果m,n∈τCName′∩τCName″,α,β∈τCProperty′∪τCProperty″∪τCOperation′∪τCOperation″,p,q∈τDataType′∪τDataType″,((p,α),m)∈λ′m∧((q,β),n)∈λ″m,m=n,α=β,p≠q,則MA和MB兩個(gè)包合并時(shí)存在數(shù)據(jù)類型沖突,表示為ConMA,MB(τDataType′,τDataType″)。
(2)"MA和MB合并時(shí)的可見性沖突,表示為ConMA,MB(τvisibility′,τvisibility″)。
(3)"MA和MB兩個(gè)包合并時(shí)的抽象性沖突,表示為ConMA,MB(τAbs′,τAbs″)。
(4)"如果m,n,p,q∈τCName′∩τCName″,(m_end:x,n_end:y)∈λ′d,(p_end:z,q_end:c)∈λ″d,x≠z∨y≠c(x,y,z,c∈N),則MA和MB兩個(gè)包合并時(shí)存在依賴關(guān)系的約束沖突,表示為ConMA,MB)(λ′d,λ′d)。
(5)"如果m,n,p,q∈τCName′∩τCName″,m=p,n=q.((m,n)∈ωAssociation′,(p,q)∈ωAggregation″)∨((m,n)∈ωAggregation′,(p,q)∈ωAssociation″),則MA和MB兩個(gè)包合并時(shí)存在關(guān)聯(lián)關(guān)系和聚合關(guān)系沖突,表示為ConMA,MB(ωAssociation,ωAggregation)。
(6)"如果m,n,p,q∈τCName′∩τCName″,m=p,n=q.((m,n)∈ωAssociation′,(p,q)∈ωComposition″)∨((m,n)∈ωComposition′,(p,q)∈ωAssociation″),則MA和MB兩個(gè)包合并時(shí)存在關(guān)聯(lián)關(guān)系和組合關(guān)系沖突,表示為ConMA,MB(ωAssociation,ωComposition)。
(7)"如果m,n,p,q∈τCName′∩τCName″,m=p,n=q.((m,n)∈ωAggregation′,(p,q)∈ωComposition″)∨((m,n)∈ωComposition′,(p,q)∈ωAggregation″),則MA和MB兩個(gè)包合并時(shí)存在關(guān)聯(lián)關(guān)系和組合關(guān)系沖突,表示為ConMA,MB(ωAggregation,ωComposition)。
后面的四種沖突都是依賴關(guān)系沖突的具體細(xì)分,它們描述了不同類型的依賴關(guān)系沖突情況。如圖3所示。
(1)"Package1中Employee類的salary屬性的數(shù)據(jù)類型為int,"Package2中Employee類的salary屬性的數(shù)據(jù)類型為float,當(dāng)Package1和Package2合并的時(shí)候存在數(shù)據(jù)類型沖突。
Package1∷Employee.salary=int,Package2∷Employee.salary=float,ConMA,MB(τDataType′,τDataType″)=(int",float).
(2)"Package1中Employee類的salary屬性的可見性為public,"Package2中Employee類的salary屬性的可見性為private,當(dāng)Package1和Package2合并的時(shí)候存在可見性沖突。
Package1∷Employee.salary.visibility=public,Package2∷Employee.salary.visibility=private,ConMA,MB(τvisibility′,τvisibility″)=(public,private).
(3)"Package1中Employee類不是抽象類,Package2中Employee類是抽象類,當(dāng)Package1和Package2合并的時(shí)候存在抽象性沖突。
Package1∷Employee.isAbstract=1,Package2∷Employee.isAbstract=true,ConMA,MB(τAbs′,τAbs″)=(1,true).
在對(duì)依賴關(guān)系的沖突進(jìn)行描述的時(shí)候,由于某些部分具有相同的表示方式,無法進(jìn)行區(qū)分。因此引入了一個(gè)下標(biāo)。該下標(biāo)僅用于區(qū)分關(guān)系,對(duì)其他部分沒有任何影響。
(4)"依賴關(guān)系的約束沖突:Con(MA,MB)(λ′d,λ″d)=(([Companyend:1,Employeeend:1],(Company,Employee)MA),([Companyend:1,Employeeend:1…*],(Company,Employee)MB)).
(5)"關(guān)聯(lián)關(guān)系沖突:ConMA,MB(ωAssociation′,ωAssociation″)=((Employee,Complany),(Complany,Employee))_MAAssociation,(Employee,Company)_MBAssociation)。
(6)如圖4所示:Package3中類A和類B之間的關(guān)系為組合關(guān)系,Package4中類A和類B之間的關(guān)系為聚合關(guān)系,當(dāng)Package3和Package4合并的時(shí)候存在聚合關(guān)系和組合關(guān)系沖突。
ConMA,MB(ωComposition,ωAggregation)=((A,B)_MAComposition,(A,B)_MBAggregation)。
4.2"沖突解決方案
一些沖突可以通過前文提出的三種合并策略來解決。然而,在這些合并策略中,對(duì)于依賴關(guān)系的沖突解決尚未明確處理。在本文的研究中,意識(shí)到了這個(gè)問題的重要性,并提出了一種解決方案,以解決這些沖突并維護(hù)系統(tǒng)的一致性。
在解決依賴關(guān)系的沖突時(shí),遵循了關(guān)聯(lián)、聚合和組合關(guān)系中約束關(guān)系的規(guī)則。當(dāng)出現(xiàn)關(guān)系沖突時(shí),選擇約束關(guān)系最強(qiáng)的那個(gè)來解決沖突。這樣做的目的是確保合并后的結(jié)構(gòu)能夠滿足系統(tǒng)設(shè)計(jì)和需求的約束,并保持一致性。具體來說,如果合并的類之間存在關(guān)聯(lián)關(guān)系,便選擇具有更嚴(yán)格約束的關(guān)聯(lián)類型。例如,如果一個(gè)類之間的關(guān)聯(lián)關(guān)系被定義為雙向關(guān)聯(lián)和單向關(guān)聯(lián),并且沖突發(fā)生在關(guān)聯(lián)的方向上,選擇雙向關(guān)聯(lián),因?yàn)樗哂懈鼜?qiáng)的約束性。同樣地,對(duì)于聚合和組合關(guān)系,也選擇具有更嚴(yán)格約束的關(guān)系類型。例如,如果一個(gè)類之間的關(guān)系被定義為聚合和組合,并且沖突發(fā)生在關(guān)系的強(qiáng)度上,選擇組合關(guān)系,因?yàn)樗哂懈鼜?qiáng)的約束性。
對(duì)于聚合和關(guān)聯(lián)之間的沖突,優(yōu)先考慮具有更嚴(yán)格約束的關(guān)系類型。例如,如果一個(gè)類之間的關(guān)系既可以被視為聚合關(guān)系,又可以被視為關(guān)聯(lián)關(guān)系,并且存在沖突時(shí),選擇聚合關(guān)系,因?yàn)樗哂懈鼜?qiáng)的約束性。類似地,在組合和關(guān)聯(lián)之間存在沖突的情況下,選擇約束關(guān)系更強(qiáng)的那個(gè)。
例如在圖3中,如果按照Package1覆蓋合并Package2的順序,可得到合并結(jié)果:Employee.salary=int,Employee.salary.visibility=public,Employee.isAbstract=1,ωAssociation=((Employee,Company),(Company,Employee))。
合并沖突的處理確保了合并后的結(jié)構(gòu)符合系統(tǒng)設(shè)計(jì)和需求的約束,從而提高系統(tǒng)的可維護(hù)性和可擴(kuò)展性,并為后續(xù)的開發(fā)和維護(hù)提供了清晰的指導(dǎo)。雖然本文介紹了解決合并沖突的方案,但需要注意,由于每個(gè)項(xiàng)目和沖突場景都具有獨(dú)特性,這些方案存在一定的不確定性和限制。此外,該解決方案是通過一系列實(shí)驗(yàn)和觀察得出的,但由于合并沖突的復(fù)雜性和多樣性,無法確保在所有情況下都能獲得最佳效果。因此,需要在實(shí)際項(xiàng)目中進(jìn)行進(jìn)一步驗(yàn)證和調(diào)整,以適應(yīng)具體的需求和限制。
4.3"不一致的發(fā)現(xiàn)與解決
在合并過程中,交換兩個(gè)包的順序可能會(huì)導(dǎo)致不同的合并結(jié)果。為了選擇與預(yù)期結(jié)果最為一致的合并順序和策略,對(duì)于不同順序下采用不同策略的合并結(jié)果進(jìn)行了比較。
在圖5中展示了兩個(gè)包的圖示以及期望得到的合并結(jié)果包。隨后,在圖6中展示了使用不同合并順序進(jìn)行覆蓋合并和聯(lián)合合并的結(jié)果。從圖中可以觀察到,當(dāng)A合并B時(shí),覆蓋合并和一般合并的結(jié)果都存在兩個(gè)不一致:(1)屬性Employee.salary的可見性是私有的,而不是公有的;(2)屬性Employee.salary的數(shù)據(jù)類型是int,而不是float。當(dāng)B合并A時(shí),覆蓋合并和一般合并所得到的結(jié)果相同,并且與期望的合并結(jié)果更為一致。因此,通過選擇那些與預(yù)期結(jié)果不一致性較小的合并順序和策略,能夠更好地控制合并過程的結(jié)果。這種方法可以幫助開發(fā)人員更準(zhǔn)確地合并模型,并減少合并過程中的不一致性。
開發(fā)人員需要能夠明確指定應(yīng)該應(yīng)用哪種合并策略,以及在定義兩個(gè)(或更多)合并關(guān)系時(shí)應(yīng)該以何種順序執(zhí)行合并策略。如果不正確地表達(dá)合并語義和執(zhí)行順序,模型合并可能成為一個(gè)容易出錯(cuò)且耗時(shí)的任務(wù)。在這個(gè)階段,接收包和合并包的模型元素可能會(huì)相互沖突,開發(fā)人員需要決定如何解決這些沖突。盡管沖突無法避免,但可以通過適當(dāng)?shù)慕鉀Q方法來解決它們。通過解決沖突和不一致,并進(jìn)行適當(dāng)?shù)恼{(diào)整和協(xié)商,可以確保在包合并過程中實(shí)現(xiàn)模型的一致性和準(zhǔn)確性。這有助于避免潛在的混淆和模糊,并促進(jìn)模型的可理解性和可維護(hù)性。
5"工具及實(shí)例研究
為了便于對(duì)包的合并進(jìn)行分析,開發(fā)了繪圖工具來繪制并將包圖轉(zhuǎn)化為形式化模型——統(tǒng)一結(jié)構(gòu)。開發(fā)的原型工具是在使用JavaScript的GoJS圖形庫作為基礎(chǔ)可視化操作界面,配合jQuery進(jìn)行開發(fā)。JavaScript是一種解釋性的腳本語言,可以基于對(duì)象進(jìn)行開發(fā),不依賴于具體的操作系統(tǒng),僅需要瀏覽器的支持。GoJS是用于構(gòu)建交互圖表和圖形的JavaScript和TypeScript庫。圖7是在工具中將UML圖轉(zhuǎn)換成統(tǒng)一結(jié)構(gòu)的一個(gè)簡單例子。
5.1"將代碼轉(zhuǎn)換成包圖
將所有代碼源文件生成的類圖放置在一個(gè)包中。使用最外層的包作為標(biāo)識(shí)來區(qū)分不同版本的開源項(xiàng)目生成的包圖。因?yàn)橐粋€(gè)項(xiàng)目通常包含大量的代碼,將整個(gè)項(xiàng)目轉(zhuǎn)換成圖形表示可能會(huì)變得復(fù)雜和冗長。因此,為了簡化分析過程,隨機(jī)選擇了部分代碼進(jìn)行轉(zhuǎn)換,將其表示為包圖。由于每個(gè)開發(fā)人員的代碼和合并需求可能不同,無法確定確切的需要合并或可能沖突的部分。因此,具體的項(xiàng)目轉(zhuǎn)換策略應(yīng)由開發(fā)人員根據(jù)實(shí)際情況自行確定。
為了進(jìn)行實(shí)際操作,在GitHub上找了一個(gè)小型的公司管理項(xiàng)目(項(xiàng)目鏈接:https://github.com/mingkong/JavaWeb)。然后,將該項(xiàng)目的部分代碼轉(zhuǎn)換為可導(dǎo)入工具的JSON格式,并將其保存為一個(gè)JSON文件。接著,對(duì)這部分代碼進(jìn)行了一些修改,并生成了第二個(gè)JSON文件以表示修改后的版本。通過將這兩個(gè)JSON文件導(dǎo)入工具中,可以得到兩個(gè)不同版本的代碼轉(zhuǎn)換成的包圖。這樣,可以在包圖上進(jìn)行進(jìn)一步的分析,以便檢測、理解和解決可能存在的沖突。
5.2"沖突檢測
將代碼轉(zhuǎn)化成包圖之后,結(jié)合之前的形式化定義對(duì)生成的兩個(gè)包圖進(jìn)行沖突檢測。
從圖7中可以看到包Package1和Package2之間一共有三處沖突:MimeTypesImpl類的屬性_mimeTypes存在可見性沖突;SecurityFilter類的方法doFilter(")存在可見性沖突,以及方法destroy(")存在數(shù)據(jù)類型沖突;IndexActionBean類和"BasicActionBean類之間存在依賴關(guān)系沖突,Package1中為Compose關(guān)系,而Package2中是generalize關(guān)系。上述實(shí)驗(yàn)結(jié)果表明工具檢測出的沖突與圖中存在的沖突一致。
本文的研究側(cè)重于為代碼合并提供合適的方案,實(shí)驗(yàn)旨在驗(yàn)證這一理論的可行性,而非進(jìn)行對(duì)比實(shí)驗(yàn)。在實(shí)際代碼合并中,該方法可以與版本控制系統(tǒng)(如Git)結(jié)合使用,以提供更好的代碼管理和合并流程。
6"結(jié)"論
采用統(tǒng)一結(jié)構(gòu)模型作為UML包圖的形式語義,系統(tǒng)地揭示了包合并的復(fù)雜性,并深入研究了包合并過程中可能出現(xiàn)的沖突和不一致性問題。通過形式化的包合并分析,將焦點(diǎn)放在了代碼合并的實(shí)踐層面,特別是包中類的合并方面。我們的研究發(fā)現(xiàn),不同的合并策略可能導(dǎo)致多種潛在的合并結(jié)果,并且合并順序?qū)ψ罱K結(jié)果具有重要影響。實(shí)驗(yàn)也驗(yàn)證了提出的方法的正確性。這些發(fā)現(xiàn)提醒著研究者在包合并領(lǐng)域中需要綜合考慮多樣性和不確定性因素,以更好地解決代碼合并過程中的挑戰(zhàn)。
通過形式化的包合并分析對(duì)代碼合并進(jìn)行探索,為軟件開發(fā)領(lǐng)域提供了一種新的視角和方法。該方法旨在提高代碼合并的準(zhǔn)確性和效率,從而推動(dòng)軟件開發(fā)過程的質(zhì)量和效率。在接下來的工作中,我們將繼續(xù)完善原型工具,使其投入實(shí)際的面向?qū)ο箝_發(fā)的系統(tǒng)建模中,為開發(fā)人員提供更好的支持和幫助。
參考文獻(xiàn)
[1]"CHAUDRON"M"R"V,"HEIJSTEK"W,"NUGROHO"A."How"effective"is"UML"modeling?[J].Software"and"Systems"Modeling,"2012,"11(4):571-580.
[2]"HOQUANG"T,"HEBIG"R,"ROBLES"G,"et"al."Practices"and"perceptions"of"UML"use"in"open"source"projects[C]."2017"IEEE/ACM"39th"International"Conference"on"Software"Engineering:"Software"Engineering"in"Practice"Track"(ICSESEIP)."IEEE,"2017:"203-212.
[3]"OMG:"‘UML:"Infrastructure"specification’,"Version"2.5.1,"https://www.omg.org/spec/UML/2.5.1/PDF,"2018."
[4]"王戟,"詹乃軍,"馮新宇,"等."形式化方法概貌[J]."軟件學(xué)報(bào),"2019,"30(1):"33-61.
[5]"CARR"B,"VANWORMHOUDT"G,"CARON"O."On"submodels"and"submetamodels"with"their"relation:"a"uniform"formalization"through"inclusion"properties[J].Software"and"Systems"Modeling,"2018,"17:"1105-1137.
[6]"BISCHOFF"V,"FARIAS"K,"GONALES"L"J,"et"al."Integration"of"feature"models:"a"systematic"mapping"study[J]."Information"and"Software"Technology,"2019,"105:"209-225.
[7]"DINGEL"J,"DISKIN"Z,"ZITO"A."Understanding"and"improving"UML"package"merge[J]."Software"and"Systems"Modeling,"2008,"7:"443-467.
[8]"KNAPP"A,"MOSSAKOWSKI"T."Multiview"consistency"in"UML:"a"survey[J]."Graph"Transformation,"Specifications,"and"Nets,"2018,"37-60.
[9]nbsp;GUESSI"M,"OLIVEIRA"L"B"R,"NAKAGAWA"E"Y."Extensions"of"UML"to"model"aspectoriented"software"systems[J]."CLEI"Electronic"Journal,"2011,14(15):"1-18.
[10]"MENS"T."A"stateoftheart"survey"on"software"merging[J]."IEEE"Transactions"on"Software"Engineering,"2002,"28(5):"449-462.
[11]"ROONEY"G,"BERLIN"D."Practical"Subversion[M]."Berkeley:Apress,"2007.
[12]"BRUN"Y,"HOLMES"R,"ERNST"M"D,"et"al."Proactive"detection"of"collaboration"conflicts[C]."Proceedings"of"the"19th"ACM"SIGSOFT"Symposium"and"the"13th"European"Conference"on"Foundations"of"Software"Engineering,2011:"168-178.
[13]"ZIMMERMANN"T."Mining"workspace"updates"in"CVS[C]."Fourth"International"Workshop"on"Mining"Software"Repositories"(MSR′07:"ICSE"Workshops"2007)."IEEE,"2007:11.
[14]"JIANG"J"M,"ZHU"H,"LI"Q,"et"al."Isolation"modeling"and"analysis"based"on"mobility[J]."ACM"Transactions"on"Software"Engineering"and"Methodology,"2019,"28(2):"1-31.
[15]"JIANG"J"M,"ZHU"H,"LI"Q,"et"al."Eventbased"functional"decomposition[J]."Information"and"Computation,"2020,"271:"104484.
[16]"GHIOTTO"G,"MURTA"L,"BARROS"M,"et"al."On"the"nature"of"merge"conflicts:"a"study"of"2,731"open"source"java"projects"hosted"by"github[J]."IEEE"Transactions"on"Software"Engineering,"2018,"46(8):"892-915.