白玲



摘要:軟件需求在整個(gè)軟件開(kāi)發(fā)生命周期中具有重要的地位,隨著開(kāi)發(fā)不斷向縱深方向發(fā)展,無(wú)論是用戶的需求,還是開(kāi)發(fā)人員對(duì)需求的理解都發(fā)生變化。本文通過(guò)對(duì)傳統(tǒng)開(kāi)發(fā)流程和敏捷開(kāi)發(fā)流程進(jìn)行分析, 運(yùn)用面向?qū)ο蟮脑O(shè)計(jì)原則和架構(gòu), 闡述進(jìn)行敏捷開(kāi)發(fā)流程下重構(gòu)技術(shù),分別從代碼重構(gòu)、設(shè)計(jì)重構(gòu)、架構(gòu)重構(gòu)和業(yè)務(wù)重構(gòu)四個(gè)方面闡述了敏捷開(kāi)發(fā)模式中重構(gòu)技術(shù)要點(diǎn)。
關(guān)鍵詞:敏捷開(kāi)發(fā) ?面向?qū)ο??重構(gòu) ?設(shè)計(jì)原則
1 概述
軟件開(kāi)發(fā)流程是指將在開(kāi)發(fā)、運(yùn)營(yíng)、維護(hù)軟件的過(guò)程中很多技術(shù)、做法、習(xí)慣和思想統(tǒng)一到一個(gè)體系中。從而能提高軟件開(kāi)發(fā)、運(yùn)營(yíng)和維護(hù)的效率,以及提升用戶滿意度、軟件的可靠性和可維護(hù)性。
經(jīng)過(guò)這些年的積累,軟件開(kāi)發(fā)模型從最早最簡(jiǎn)單的
瀑布模型開(kāi)始發(fā)展出了包括原型法、演化原型法、增量開(kāi)發(fā)、螺旋模型、V 模型、混沌模型和近年流行的敏捷開(kāi)發(fā)模式。
2 敏捷開(kāi)發(fā)特點(diǎn)
敏捷開(kāi)發(fā)是一種采取迭代開(kāi)發(fā)方式,以人作為驅(qū)動(dòng)核心的一種軟件開(kāi)發(fā)流程。團(tuán)隊(duì)成員無(wú)縫的交流,如每天短時(shí)間的站立會(huì)議。拒絕使用一切形式化的東西,使用簡(jiǎn)單易用的工具開(kāi)始工作。在需求變化越來(lái)越不確定和產(chǎn)品原型周期要求越來(lái)越短的今天,敏捷開(kāi)發(fā)模式被越來(lái)越多的開(kāi)發(fā)團(tuán)隊(duì)所接受。
理論上看敏捷方法論無(wú)比完美:
■
圖1 ?敏捷流程圖
第一步:找出完成項(xiàng)目需要做的事情。圖中Product Backlog,是指“積壓的任務(wù)”或“待解決的問(wèn)題”。Backlog的管理工作主要由Scrum Master來(lái)主導(dǎo)。
第二步:當(dāng)前的沖刺主要需要解決的事情 Sprint Backlog任務(wù)被進(jìn)一步細(xì)化為小的Task。如果一個(gè)任務(wù)的估計(jì)時(shí)間太長(zhǎng),那么它就應(yīng)該被進(jìn)一步分解。
第三步:沖刺(Sprint)。在沖刺階段,一切對(duì)交流只能通過(guò)Scrum Master來(lái)完成。沖刺期間 ,每天要開(kāi)一個(gè)每日 “站會(huì)”,大家依次報(bào)告各自每天的進(jìn)度情況。平且有任何需求的改變都留待沖刺結(jié)束后再討論。
在完成項(xiàng)目之前,通常使用燃盡圖來(lái)對(duì)需要完成的工作的一種可視化表示(圖2)。
在燃盡圖中,縱軸、橫軸分別代表工作和時(shí)間。在理想情況下,燃盡圖應(yīng)是一個(gè)向下的曲線,直到完成剩余的工作,“燒盡”至零。
3 敏捷開(kāi)發(fā)中的重構(gòu)
所謂重構(gòu)(Refactoring)就是對(duì)軟件現(xiàn)有的功能進(jìn)行充分的利用,通過(guò)對(duì)程序代碼進(jìn)行調(diào)整,進(jìn)一步提高軟件的質(zhì)量,豐富軟件的性能,在一定程度上使程序的設(shè)計(jì)模式和架構(gòu)趨于合理化,從而提高軟件的可擴(kuò)展性和可維護(hù)性。從本質(zhì)上說(shuō),重構(gòu)就是調(diào)整軟件的內(nèi)部結(jié)構(gòu),其目的主要是在現(xiàn)有軟件功能的基礎(chǔ)上,降低軟件的修改成本,同時(shí)提高軟件的可理解性。對(duì)于重構(gòu)的方式,通常情況下可以分為代碼重構(gòu)、設(shè)計(jì)重構(gòu)、架構(gòu)重構(gòu)和業(yè)務(wù)重構(gòu)。
3.1 代碼重構(gòu)
代碼重構(gòu)是指在編碼規(guī)范層面上對(duì)細(xì)粒度代碼實(shí)行規(guī)范化的過(guò)程。代碼重構(gòu)由于其是處在方法級(jí)別重構(gòu)技術(shù),所以無(wú)論是在傳統(tǒng)開(kāi)發(fā)流程還在敏捷開(kāi)發(fā)模式中都適應(yīng)。下面是一些常用代碼重構(gòu)方法:
①封裝成員變量:將僅限于本類(lèi)使用的變量重寫(xiě)成私有成員變量,并提供訪問(wèn)方法。這種重構(gòu)方式可以將與外部調(diào)用者無(wú)關(guān)的變量隱藏起來(lái),減少代碼的耦合性,并減少意外出錯(cuò)的概率。
②提取方法:將大段代碼中的一部分提取后,構(gòu)成一個(gè)新方法。這種重構(gòu)可以使整段程序的結(jié)構(gòu)變得更清晰,從而增加可讀性。這也對(duì)函數(shù)通用。
③一般化類(lèi)型:將多個(gè)類(lèi)/函數(shù)共用的類(lèi)型抽象出可以公用的基類(lèi),然后利用多態(tài)性追加每個(gè)類(lèi)/函數(shù)需要的特殊函數(shù)。這種重構(gòu)可以讓結(jié)構(gòu)更加清晰,同時(shí)可以增加代碼的可維護(hù)性。
④函數(shù)歸父:也叫函數(shù)上移,是指將子類(lèi)方法上移到父類(lèi)。避免行為的重復(fù)性。雖然重復(fù)的兩個(gè)函數(shù)可以各自工作,但是,對(duì)自身進(jìn)行重復(fù),會(huì)成引發(fā)錯(cuò)誤。無(wú)論在任何情況下,系統(tǒng)內(nèi)部只要出現(xiàn)重復(fù),同時(shí)只能修改其中的一個(gè)。
⑤函數(shù)歸子:也叫函數(shù)下移,是指將父類(lèi)的方法下移到子類(lèi)。函數(shù)歸子恰恰相反于函數(shù)歸父。在必要的情況下,將某些行為從父類(lèi)移至特定的子類(lèi)時(shí),這時(shí)就可以使用函數(shù)歸子,它通常也只在這種時(shí)候有用。
⑥方法更名:將方法名稱以更好的表達(dá)它的用途。方法更名說(shuō)的簡(jiǎn)單點(diǎn)就是把方法啟一個(gè)與它功能相對(duì)應(yīng)的名稱,當(dāng)你的方法是求和操作時(shí),你的方法名應(yīng)該是Sum(int param),而不要寫(xiě)成a(int param)。
3.2 軟件設(shè)計(jì)重構(gòu)
設(shè)計(jì)重構(gòu)是在代碼重構(gòu)之上更高級(jí)別重構(gòu)技術(shù),通常(面向?qū)ο笳Z(yǔ)言中)采取面向?qū)ο蟮姆治龊驮O(shè)計(jì)原則,選擇合適的設(shè)計(jì)原則和設(shè)計(jì)模式來(lái)構(gòu)建類(lèi)之間依賴關(guān)系。在敏捷開(kāi)發(fā)中通常采取如下設(shè)計(jì)重構(gòu)方法:
①單一職責(zé)原則:對(duì)于一個(gè)類(lèi)來(lái)說(shuō),引起它變化的原因應(yīng)該僅有一個(gè)。簡(jiǎn)單地說(shuō),就是一個(gè)類(lèi)只具有一個(gè)功能,這是因?yàn)?,如果一個(gè)類(lèi)能夠?qū)崿F(xiàn)兩個(gè)功能,必然造成一個(gè)功能的變動(dòng)會(huì)污染另外一個(gè)功能的代碼。
②開(kāi)放-封閉原則:類(lèi)、模塊、函數(shù)等軟件實(shí)體,通常情況下都是可以擴(kuò)展的,但是不可對(duì)其進(jìn)行修改。簡(jiǎn)單地說(shuō),該原則的極限情況是,如果完成一個(gè)軟件實(shí)體,那么這個(gè)軟件實(shí)體以后不允許改動(dòng),而且,當(dāng)添加新功能時(shí),在不修改原來(lái)的代碼的基礎(chǔ)上可以繼續(xù)書(shū)寫(xiě)代碼。在社會(huì)實(shí)踐中,雖然達(dá)不到這種理想情況,但是可以接近,通常情況下,這種接近的狀態(tài)就是一種比較完美的狀態(tài)。
③Liskov替換原則:子類(lèi)型必須能對(duì)它們的基類(lèi)型進(jìn)行替換。簡(jiǎn)單的說(shuō),該原則就,如果不是基于“is-a”的原則進(jìn)行繼承,這種情況下比較危險(xiǎn),這是因?yàn)?,由于時(shí)間、開(kāi)發(fā)者之間存在差異,在一定程度上可能導(dǎo)致子類(lèi)型替換父類(lèi)型。
④依賴倒置原則:對(duì)于高層模塊來(lái)說(shuō),不能對(duì)低層模塊形成依賴,二者之間應(yīng)該依賴于抽象。簡(jiǎn)單的說(shuō),因?yàn)檐浖牟呗圆糠趾蜆I(yè)務(wù)模型主要集中在高層模塊,這是軟件的主要特征。另外,在實(shí)際編程過(guò)程中,高層模塊是應(yīng)用最多的,在很多庫(kù)的支持下,細(xì)節(jié)模塊不再那么重要。在這種情況下,可以說(shuō),高層不依賴于低層。
⑤接口隔離原則:在實(shí)際使用過(guò)程中,防止客戶依賴它們不用的方法。簡(jiǎn)單地說(shuō),就是將接口進(jìn)行內(nèi)聚處理,如果接口缺乏相應(yīng)的內(nèi)聚性,在這種情況下,就會(huì)出現(xiàn)接口中的某些方法會(huì)被污染。這是因?yàn)椋?dāng)一個(gè)客戶使用的接口中包含他不需要的方法時(shí),這時(shí)改動(dòng)客戶不需要的方法,就會(huì)對(duì)客戶的接口造成污染,進(jìn)而在一定程度上污染了客戶的代碼。
3.3 系統(tǒng)架構(gòu)重構(gòu)
對(duì)于傳統(tǒng)的架構(gòu)設(shè)計(jì),通常情況下主要包括兩個(gè)方面,分別為架構(gòu)和設(shè)計(jì)。其中,設(shè)計(jì)包含詳細(xì)設(shè)計(jì)(詳細(xì)的類(lèi)圖,順序圖等UML圖)、詳細(xì)的API設(shè)計(jì)以及接口描述,存儲(chǔ)層數(shù)據(jù)庫(kù)表字段設(shè)計(jì)等。當(dāng)前,隨著社會(huì)節(jié)奏的不斷加快,進(jìn)一步使得業(yè)務(wù)需求、技術(shù)等都在快速地變化著,在進(jìn)行架構(gòu)設(shè)計(jì)時(shí),前期花費(fèi)的時(shí)間約占30%。在進(jìn)行需求分析時(shí),如果分析不徹底,就會(huì)導(dǎo)致開(kāi)發(fā)出的軟件不符合市場(chǎng)需求,甚至需求發(fā)生變動(dòng),就會(huì)改動(dòng)成本。如圖3所示,描述了敏捷開(kāi)發(fā)前和后架構(gòu)方式:
■
圖3 ?敏捷開(kāi)發(fā)前后架構(gòu)設(shè)計(jì)方式
3.4 業(yè)務(wù)流程重構(gòu)
業(yè)務(wù)流程重構(gòu)即BPR,BPR的思想是指精簡(jiǎn)企業(yè)機(jī)構(gòu)設(shè)置,簡(jiǎn)化企業(yè)業(yè)務(wù)沉程,以降低經(jīng)營(yíng)運(yùn)行成本,提高企業(yè)經(jīng)濟(jì)效益,大限度地減少或精簡(jiǎn)不必要的業(yè)務(wù)流程。隨著大數(shù)據(jù)、云計(jì)算、移動(dòng)設(shè)備、社交商務(wù)等IT趨勢(shì)的發(fā)展,新業(yè)務(wù)形態(tài)對(duì)IT基礎(chǔ)架構(gòu)帶來(lái)了新的挑戰(zhàn)。
4 結(jié)束語(yǔ)
對(duì)于代碼來(lái)說(shuō),需要明確它要做的內(nèi)容,對(duì)于如何做的問(wèn)題,需要通過(guò)重構(gòu)來(lái)解決。重構(gòu)的目的就是通過(guò)對(duì)程序代碼進(jìn)行調(diào)整,進(jìn)而在一定程度上提高軟件的質(zhì)量,豐富軟件的性能,使得程序的設(shè)計(jì)模式、架構(gòu)趨于合理,同時(shí)提高軟件的可擴(kuò)展性和可維護(hù)性。對(duì)于軟件產(chǎn)品來(lái)說(shuō),最初制造出來(lái),通常情況下需要經(jīng)過(guò)精心設(shè)計(jì),并且具備良好的架構(gòu)。但是,隨著時(shí)間的延長(zhǎng),用戶的需求發(fā)生了變化,在這種情況下需要對(duì)原有的功能進(jìn)行修改,或者添加新的功能。在這一過(guò)程中,需要對(duì)軟件存在的缺陷進(jìn)行修改和完善。為了不斷滿足用戶的需求,違反最初設(shè)計(jì)架構(gòu)的行為不可避免。當(dāng)難以實(shí)現(xiàn)用戶的新需求時(shí),對(duì)于新的需求,軟件的架構(gòu)逐漸喪失支撐能力,最終成為約束。
綜上所述,敏捷開(kāi)發(fā)作為一種開(kāi)發(fā)軟件的思想,這種思想滲透到各種軟件開(kāi)發(fā)工具中。在開(kāi)發(fā)軟件的過(guò)程中,重構(gòu)作為敏捷開(kāi)發(fā)的重要環(huán)節(jié),憑借該思想,可以幫助開(kāi)發(fā)人員提高開(kāi)發(fā)軟件的效率。
參考文獻(xiàn):
[1]Robert C Martin.敏捷軟件開(kāi)發(fā)-原則、模式與實(shí)踐[M].北京:清華大學(xué)出版社,2003.
[2]貝克(Beck,K.).解析極限編程:擁抱變化[M].2版.北京:電子工業(yè)出版社,2006.5.
[3]鄒欣.構(gòu)建之法:現(xiàn)代軟件工程[M].北京:人民郵電出版社,2014.9.
[4]范鋼.大話重構(gòu)[M].北京:人民郵電出版社,2014.5.1.
[5]Alistair Cockburn著.Agile Software Development[M].蘇敬凱譯.機(jī)械工業(yè)出版社,2008.
[6]張?jiān)?論銀彈的存在[J].計(jì)算機(jī)教育,2004.7:35-37.
[7]黃敏.用極限編程解決軟件開(kāi)發(fā)項(xiàng)目中的常見(jiàn)問(wèn)題[J].電子科技,2004.3:43-45.
[8]徐景周.極限編程與敏捷開(kāi)發(fā).On-line at http://www.vckbase.com/document/view doc/?id=1027.
[9]Martin Fowler.《重構(gòu):改善既有代碼的設(shè)計(jì)(中文版)》[M].候捷譯.中國(guó)電力出版社.
[10](美)Joshua Kerievsky.《重構(gòu)與模式》[M].楊光譯.人發(fā)郵電出版社.