版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、編輯課件如何提高產(chǎn)品開發(fā)品質(zhì)如何提高產(chǎn)品開發(fā)品質(zhì)編輯課件講解內(nèi)容講解內(nèi)容目前開發(fā)過程存在的問題1產(chǎn)品開發(fā)品質(zhì)保障流程2代碼重構(gòu)3測試驅(qū)動4日構(gòu)建5編輯課件一、目前開發(fā)過程存在的問題一、目前開發(fā)過程存在的問題l沒有完善的品質(zhì)保障流程沒有完善的品質(zhì)保障流程l質(zhì)量低下的代碼質(zhì)量低下的代碼l不重視測試不重視測試編輯課件產(chǎn)品開發(fā)流程現(xiàn)狀產(chǎn)品開發(fā)流程現(xiàn)狀開發(fā)人員編寫代碼開發(fā)人員編寫代碼調(diào)試調(diào)試, 肉眼觀察肉眼觀察有問題有問題沒問題(自認(rèn)為)沒問題(自認(rèn)為)可交付的代碼可交付的代碼編譯編譯修正編譯錯誤修正編譯錯誤登記到登記到JIRAJIRA上上客戶提出需求或客戶提出需求或現(xiàn)場發(fā)現(xiàn)現(xiàn)場發(fā)現(xiàn)bugbug編輯課件
2、產(chǎn)品品質(zhì)管理嚴(yán)重缺失產(chǎn)品品質(zhì)管理嚴(yán)重缺失 該流程的最終目標(biāo)和工作重心都是完成產(chǎn)品功能開發(fā),品質(zhì)管理嚴(yán)重缺失。產(chǎn)品的開發(fā)質(zhì)量完全靠開發(fā)人員的個人責(zé)任心以及工作經(jīng)驗(yàn)來保障,缺乏一個穩(wěn)定可靠的質(zhì)量保障流程。這種流程開發(fā)出來的產(chǎn)品往往是質(zhì)量不可靠,需要經(jīng)常返工的劣質(zhì)產(chǎn)品。編輯課件質(zhì)量低下的代碼是導(dǎo)致產(chǎn)品品質(zhì)質(zhì)量低下的代碼是導(dǎo)致產(chǎn)品品質(zhì)不好的根本原因不好的根本原因質(zhì)量低下的代碼體現(xiàn)在以下幾個方面:l重復(fù)的代碼l過長的函數(shù)l過大類l過長的參數(shù)列表l過度復(fù)雜的邏輯判斷l(xiāng)數(shù)據(jù)泥團(tuán)編輯課件沒有專職測試人員來進(jìn)行功能性沒有專職測試人員來進(jìn)行功能性測試工作測試工作在目前的開發(fā)流程中,開發(fā)出來的代碼只經(jīng)過開發(fā)人員自己
3、簡單的測試,沒有專職的測試人員來進(jìn)行詳細(xì)的功能性測試。這樣導(dǎo)致的結(jié)果往往是提交到現(xiàn)場的代碼會帶有不少BUG,一定要經(jīng)過多次返工才能達(dá)到較高的品質(zhì)。而且這樣做的另一個后果是把客戶當(dāng)作測試人員,會給客戶留下產(chǎn)品品質(zhì)不穩(wěn)定這樣一種非常不好的客戶體驗(yàn)。編輯課件開發(fā)人員在開發(fā)過程中不重視單開發(fā)人員在開發(fā)過程中不重視單元測試元測試單元測試是提高產(chǎn)品品質(zhì)非常重要的一個方法,而我們的開發(fā)人員往往會忽視這一點(diǎn)。如果沒有單元測試,僅僅依靠測試人員的功能性測試,那么這樣的測試工作量會非常大,每次修改一個功能,可能會影響到的其他功能都要一一測試,不僅測試時(shí)間會非常長,而且效果也不好,很多細(xì)節(jié)不一定每次都能測到,這些都
4、是產(chǎn)生BUG的隱患。同時(shí)由于我們業(yè)務(wù)需求都非常復(fù)雜多變的,沒有一個完善自動化測試流程,而僅僅依靠人工測試,對產(chǎn)品品質(zhì)的影響是不言而喻的。編輯課件我們的目標(biāo)!我們的目標(biāo)!l編寫出邏輯清晰、結(jié)構(gòu)簡潔、擴(kuò)展性良好、可測試性高的優(yōu)秀代碼。l強(qiáng)化單元測試工作,提高單元測試覆蓋率,搭建自動單元測試集,通過日構(gòu)建來持續(xù)集成,對產(chǎn)品質(zhì)量進(jìn)行全面控制。l通過嚴(yán)格的產(chǎn)品質(zhì)量管理流程,強(qiáng)化質(zhì)量管理工作,將所有BUG消滅在公司內(nèi)部。編輯課件二、產(chǎn)品開發(fā)品質(zhì)保障流程二、產(chǎn)品開發(fā)品質(zhì)保障流程編輯課件開發(fā)質(zhì)量管理開發(fā)質(zhì)量管理本開發(fā)流程的目標(biāo)是開發(fā)出質(zhì)量優(yōu)良的產(chǎn)品,流程的重心在于質(zhì)量管控,通過質(zhì)量保障人員對產(chǎn)品質(zhì)量進(jìn)行全面把
5、關(guān)。l對于沒有編寫單元測試的代碼直接打回!l質(zhì)量保障人員負(fù)責(zé)進(jìn)行功能性測試,并對提交出去的代碼負(fù)責(zé)。l質(zhì)量保障人員另一個職責(zé)是思考如何持續(xù)改進(jìn)產(chǎn)品質(zhì)量。編輯課件需求管控需求管控l對每個需求進(jìn)行分級評審,最大程度的降低需求變更的頻度。l所有需求開發(fā)前都經(jīng)過內(nèi)部評審,對于一些復(fù)雜需求把握更加準(zhǔn)確,不至于在開發(fā)時(shí)候產(chǎn)生較大偏差。l所有需求的開發(fā)工作都有經(jīng)過客戶簽字的開發(fā)工作量評估,為商務(wù)工作開展創(chuàng)造有利條件。l所有需求都有詳細(xì)開發(fā)計(jì)劃,片區(qū)人員可以安排相應(yīng)的測試計(jì)劃。編輯課件全過程管控全過程管控l所有缺陷和經(jīng)過評審的需求都必須在JIRA上登記,否則不予開發(fā)。l開發(fā)計(jì)劃通過JIRA進(jìn)行精確體現(xiàn)。l片區(qū)
6、人員可以通過JIRA實(shí)時(shí)跟蹤產(chǎn)品開發(fā)進(jìn)度。l方便后續(xù)各類工作量的統(tǒng)計(jì)。編輯課件三、利用代碼重構(gòu)來提高代碼質(zhì)量三、利用代碼重構(gòu)來提高代碼質(zhì)量 重構(gòu)(Refactoring):是對軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在不改變外部行為的前提下,提高其可理解性,降低其修改成本編輯課件為什么重構(gòu)(為什么重構(gòu)(1)l改進(jìn)軟件的設(shè)計(jì)。l程序員對代碼所做的為了滿足短期利益代碼改動,或再沒有完全清楚增個架構(gòu)下的改動,都很容易是代碼失去它的清晰結(jié)構(gòu),偏離需求或設(shè)計(jì)。而這些改動的積累很容易使代碼偏離它原先設(shè)計(jì)的初衷而變得不可立即和無法維護(hù)。l重構(gòu)則幫助重新組織代碼,重新清晰的體現(xiàn)結(jié)構(gòu)和進(jìn)一步改進(jìn)設(shè)計(jì)。編輯課件為什么重構(gòu)(
7、為什么重構(gòu)(2)l提高代碼質(zhì)量,更易被理解l容易理解的代碼可以很容易的維護(hù)和做進(jìn)一步的開發(fā)。即使對寫這些代碼的程序員本身,容易理解代碼也可以幫助容易地做修改。程序代碼也是文檔。而代碼首先是寫給人看的,讓后才是給計(jì)算機(jī)看的。l重構(gòu)幫助盡早的發(fā)現(xiàn)錯(Bugs)l重構(gòu)是一個code review和反饋的過程。在另一個時(shí)段重新審視自己或別人代碼,可以更容易的發(fā)現(xiàn)問題和加深對代碼的理解。l重構(gòu)是一個良好的軟件開發(fā)習(xí)慣。編輯課件為什么重構(gòu)(為什么重構(gòu)(3)l重構(gòu)可以提高開發(fā)速度l重構(gòu)對設(shè)計(jì)和代碼的改進(jìn),都可以有效的提高開發(fā)速度。好的設(shè)計(jì)和代碼質(zhì)量實(shí)體提高開發(fā)速度的關(guān)鍵。在一個有缺陷的設(shè)計(jì)和混亂代碼基礎(chǔ)上的
8、開發(fā),即使表面上進(jìn)度較快,但本質(zhì)是試延后對設(shè)計(jì)缺陷的發(fā)現(xiàn)和對錯誤的修改,也就是延后了開發(fā)風(fēng)險(xiǎn),最終要在開發(fā)的后期付出更多的時(shí)間和代價(jià)。l項(xiàng)目的維護(hù)成本遠(yuǎn)高于開發(fā)成本.編輯課件何時(shí)重構(gòu)何時(shí)重構(gòu)? ?l添加或者修改功能時(shí)一并重構(gòu)l為了增加一個新的功能或者修改原有的功能,程序員需要首先讀懂現(xiàn)有的代碼。l修補(bǔ)錯誤時(shí)一并重構(gòu)l為了修復(fù)一個Bug,程序員需要讀懂現(xiàn)有的代碼。lCode Review時(shí)一并重構(gòu)編輯課件何時(shí)不該重構(gòu)何時(shí)不該重構(gòu)? ?l代碼太混亂,設(shè)計(jì)完全錯誤。與其Refactor,不如重寫。l明天是DeadLinel永遠(yuǎn)不要做Last-Minute-Change。推遲重構(gòu),但不可以忽略,即使進(jìn)
9、入產(chǎn)品期的代碼都正確的運(yùn)行。編輯課件重構(gòu)方法介紹:提取函數(shù)(重構(gòu)方法介紹:提取函數(shù)(1)String name = request.getParameter(Name);if( name != null & name.length() 0 ).String age = request.getParameter(Age);if( age != null & age.length() 0 ).String name = request.getParameter(Name);if( !isNullOrEmpty( name ) ).String age = request.getPa
10、rameter(Age);if( !isNullOrEmpty( age ) ).private boolean isNullOrEmpty( final String string )if( string != null & string.length() 0 )return true;elsereturn false;編輯課件重構(gòu)方法介紹:提取函數(shù)(重構(gòu)方法介紹:提取函數(shù)(2) 提取函數(shù)是我最常用的重構(gòu)手法之一。當(dāng)我看見一個過長的函數(shù)或者一段需要注釋才能讓人理解用途的代碼,我就會將這段代碼放進(jìn)一個獨(dú)立的函數(shù)中。有數(shù)個原因造成我喜歡簡短而有良好命名的函數(shù)。首先,如果每個函數(shù)的粒度都很
11、小,那么函數(shù)之間彼此復(fù)用的機(jī)會就更大;其次,這會使高層函數(shù)讀起來就像一系列注釋;再者,如果函數(shù)都是細(xì)粒度,那么函數(shù)的覆寫(override )也會更容易些: 的確,如果你習(xí)慣了看大型函數(shù),恐怕需要一段時(shí)問才能適應(yīng)達(dá)種新風(fēng)格,而且只有當(dāng)你能給小型函數(shù)很好地命名時(shí),它們才能真正起作用,所以你需要在函數(shù)名稱下點(diǎn)功夫,一個函數(shù)多長才算合適?在我看來.長度不是問題,關(guān)鍵在于函數(shù)名稱和函數(shù)本體之間的語義距離,如果提煉動作可以強(qiáng)化代碼的清晰度,那就去做,就是函數(shù)名稱比提煉出來的代碼還長也無所謂。編輯課件重構(gòu)方法介紹:去除臨時(shí)變量重構(gòu)方法介紹:去除臨時(shí)變量(1)(1)編輯課件重構(gòu)方法介紹:去除臨時(shí)變量重構(gòu)方法
12、介紹:去除臨時(shí)變量(2)(2)我喜歡盡量除去函數(shù)內(nèi)的臨時(shí)變量。臨時(shí)變量往往形成問題,它們會導(dǎo)致大量參數(shù)被傳來傳去,而其實(shí)完全沒有這種必要。你很容易失去它們的蹤跡,尤其在長長的函數(shù)之中更是如此。而且,臨時(shí)變量的存在,往往會阻礙提取函數(shù)等其他重構(gòu)手法的進(jìn)行。編輯課件重構(gòu)方法介紹:重新命名函數(shù)重構(gòu)方法介紹:重新命名函數(shù)(1)(1)public String getItemName (int itemSort,String itemName)return +itemSort+、+itemName; public String formatItemName (int itemSort,String it
13、emName)return +itemSort+、+itemName; 編輯課件重構(gòu)方法介紹:重新命名函數(shù)重構(gòu)方法介紹:重新命名函數(shù)(2)(2)我極力提倡的一種編程風(fēng)格就是:將復(fù)雜的處理過程分解成小函數(shù)。但是,如果做得不好,這會使你費(fèi)盡周折卻弄不清楚這些小函數(shù)各白的用途、.要避免這種麻煩,關(guān)鍵就在于給函數(shù)起一個好名稱;函數(shù)的名稱應(yīng)該準(zhǔn)確表達(dá)它的用途;給函數(shù)命名有一個好辦法。首先考慮應(yīng)該給這個函數(shù)寫上一句怎樣的注釋,然后想辦法將注釋變成函數(shù)名稱。人生不如意十之八九:你常常無法第一次就給函數(shù)起一個好名稱,這時(shí)候你可能會想,就這樣將就著吧,畢竟只是一個名稱而已。當(dāng)心!這是惡魔的召喚,是通向混亂之路,
14、千萬不要被它誘惑!如果你看到一個函數(shù)名稱不能很好地表達(dá)它的用途,應(yīng)該馬上加以修改。記住,你的代碼首先是為人寫的,其次才是為計(jì)算器寫的。而人需要良好名稱的函數(shù)。想想過去曾經(jīng)浪費(fèi)的無數(shù)時(shí)間吧,如果給每個函數(shù)都起一個良好的名稱,也許你可以節(jié)約好多時(shí)間。取一個好名稱并不容易,需要經(jīng)驗(yàn),要想成為一個真正的編程高手,取名稱的水平是至關(guān)重要的。編輯課件重構(gòu)方法介紹:以多態(tài)取代條件重構(gòu)方法介紹:以多態(tài)取代條件表達(dá)式(表達(dá)式(1 1)public class PlanUtil public void setPlanState(int planYear,int itemId,int dataType)switch
15、 dataType case 1:setPrePlanState(planYear,itemId); case 2:setColPlanState(planYear,itemId); case 3:setA(planYear,itemId); default:throw new RuntimeException(不正確的計(jì)劃類型:+dataType);/.更新建議計(jì)劃狀態(tài)public void setPrePlanState /.更新綜合計(jì)劃狀態(tài)public void setColPlanState. /.更新開工計(jì)劃狀態(tài)public void setA.public class PlanUt
16、il public static PlanUtil create (int dataType)switch (dataType)case 1:return new PrePlanUtil();case 2:return new ColPlanUtil();case 3:return new A();default:throw new RuntimeException(不正確的計(jì)劃類型:+dataType);public abstract void setPlanState (int planYear,int itemId,int dataType);public abstract void s
17、avePlan (int planYear,int itemId,int dataType);編輯課件重構(gòu)方法介紹:以多態(tài)取代條件重構(gòu)方法介紹:以多態(tài)取代條件表達(dá)式(表達(dá)式(2)/保存計(jì)劃數(shù)據(jù)public void savePlan(int planYear,int itemId,int dataType)switch dataTypecase 1:savePrePlan(planYear,itemId);case 2:saveColPlan(planYear,itemId);case 3:saveA(planYear,itemId); default: throw new RuntimeEx
18、ception(不正確的計(jì)劃類型:+dataType);/.保存建議計(jì)劃數(shù)據(jù)public void savePrePlan /.保存綜合計(jì)劃數(shù)據(jù)public void saveColPlan/.保存開工計(jì)劃數(shù)據(jù)public void saveApublic class PrePlanUtil extends PlanUtil public void setPlanState (int planYear,int itemId,int dataType). 更新建議計(jì)劃狀態(tài)方法public void savePlan (int planYear,int itemId,int dataType)保存
19、建議計(jì)劃數(shù)據(jù)方法public class ColPlanUtil extends PlanUtil public void setPlanState (int planYear,int itemId,int dataType). 更新綜合計(jì)劃狀態(tài)方法public void savePlan (int planYear,int itemId,int dataType)保存綜合計(jì)劃數(shù)據(jù)方法編輯課件重構(gòu)方法介紹:以多態(tài)取代條件重構(gòu)方法介紹:以多態(tài)取代條件表達(dá)式(表達(dá)式(3)/調(diào)用更新計(jì)劃狀態(tài)的方法planUtil.setPlanState(year,itemId,dataType);/調(diào)用保存計(jì)劃數(shù)
20、據(jù)的方法planUtil.savePlanyear,itemId,dataType);public class AftPlanUtil extends PlanUtil public void setPlanState (int planYear,int itemId,int dataType). 更新開工計(jì)劃狀態(tài)方法public void savePlan (int planYear,int itemId,int dataType)保存開工計(jì)劃數(shù)據(jù)方法/調(diào)用PlanUtil planUtil = PlanUtil .create(dataType);/調(diào)用更新計(jì)劃狀態(tài)的方法planUtil.
21、setPlanState(year,itemId,dataType);/調(diào)用保存計(jì)劃數(shù)據(jù)的方法planUtil.savePlan (year,itemId,dataType);編輯課件重構(gòu)方法介紹:以多態(tài)取代條件重構(gòu)方法介紹:以多態(tài)取代條件表達(dá)式(表達(dá)式(4)l多態(tài)最根本的好處就是:如果你需要根據(jù)對象的不同型別而采取不同的行為,多態(tài)使你不必編寫明顯的條件式。正因?yàn)橛辛硕鄳B(tài),所以你會發(fā)現(xiàn):針對type code(型別碼)而寫的switch語句,以及針對type string(型別名稱字符串)而寫的if-then-else語句在面向?qū)ο蟪绦蛑泻苌俪霈F(xiàn)。l多態(tài)能夠給你帶來很多好處。如果同一組條件式在
22、程序許多地點(diǎn)出現(xiàn),那么使用多態(tài)的收益是最大的。使用條件式時(shí),如果你想添加一種新型別,就必須杳找并更新所有條件式。但如果改用多態(tài),只需建一個新的subclass并在其中提供適當(dāng)?shù)暮瘮?shù)就行了。class用戶不需要了解這個subclass,這就大大降低了系統(tǒng)各部分之間的耦合程度,使系統(tǒng)升級.更加容易。編輯課件重構(gòu)方法介紹:以委托取代繼承重構(gòu)方法介紹:以委托取代繼承(1)(1)/繼承解決方案public classBusPlanManagerServiceImpl public void setPlanState (int planYear,int itemId,int dataType). 更新建議
23、計(jì)劃狀態(tài)方法 public void savePlan (int planYear,int itemId,int dataType)保存建議計(jì)劃數(shù)據(jù)方法public class PrePlanService extends BusPlanManagerServiceImpl .public class ColPlanService extends BusPlanManagerServiceImpl .public class AftPlanService extends BusPlanManagerServiceImpl ./委托解決方案public classBusPlanManagerSe
24、rviceImplpublic void setPlanState (int planYear,int itemId,int dataType)PlanUtil planUtil = PlanUtil .create(dataType);/調(diào)用更新計(jì)劃狀態(tài)的方法planUtil.setPlanState(year,itemId,dataType);public void savePlan (int planYear,int itemId,int dataType)PlanUtil planUtil = PlanUtil .create(dataType);/調(diào)用更新計(jì)劃狀態(tài)的方法planUti
25、l. savePlan (year,itemId,dataType); 編輯課件重構(gòu)方法介紹:以委托取代繼承重構(gòu)方法介紹:以委托取代繼承(2)(2)l繼承是一件很棒的事,但有時(shí)候它并不是你要的。常常你會遇到這樣的情況:一開始你繼承了一個class ,隨后發(fā)現(xiàn)superclass中的許多操作井不真正適用于subclass。這種情況下你所擁有的接口并末真正反映出class的功能?;蛘撸憧赡馨l(fā)現(xiàn)你從superclass中繼承了一大堆subclas并不需要的數(shù)據(jù),抑或者你可能發(fā)現(xiàn)superclass中的某些protected函數(shù)對subclass并沒有什么意義。l你可以選擇容忍,并接受傳統(tǒng)說法:su
26、bclass可以只使用superclas、功能的一部分。但這樣做的結(jié)果是:代碼傳達(dá)的信息與你的意圖南轅北轍,這是一種混淆,你應(yīng)該將它去除。如果以委托取代繼承,你可以更清楚地表明:你只需要受托類的一部分功能。接口中的哪一部分應(yīng)該被使用,哪一部分應(yīng)該被忽略,完全由你主導(dǎo)控制。這樣做的成本則是需耍額外寫出委托函數(shù),但這些函數(shù)都非常簡單,極少可能出錯。編輯課件重構(gòu)方法介紹:引入?yún)?shù)對象重構(gòu)方法介紹:引入?yún)?shù)對象(1)public List getYearPlanList (String operatorID, String planYear,String iSeason, String planTyp
27、e,String dataType).public List getLastYearPlanList (String operatorID, String planYear,String iSeason, String planType,String dataType)public void fillPlanData (String operatorID, String planYear,String iSeason, String planType,String dataType)PlanData planData=new PlanData();planData.setYeraPlanLis
28、t(getYearPlanList (operatorID,planYear, iSeason,planType,dataType);planData.setLastYeraPlanList(getLastYearPlanList (operatorID,planYear, iSeason,planType,dataType);public class PlanParamObj private String operatorID;private String planYear;private String iSeason;private String planType,;private Str
29、ing dataType;public PlanParamObj (String operatorID, String planYear,String iSeason, String planType,String dataType) this.operatorID=operatorID;this.planYear=planYear;this.iSeason=iSeason;this.planType=planType;this.dataType=dataType;編輯課件重構(gòu)方法介紹:引入?yún)?shù)對象重構(gòu)方法介紹:引入?yún)?shù)對象(2)public List getYearPlanList (Pla
30、nParamObj paramObj).public List getLastYearPlanList (PlanParamObj paramObj).public void fillPlanData (String operatorID, String planYear,String iSeason, String planType,String dataType)PlanParamObj paramObj = new PlanParamObj (operatorID,planYear, iSeason,planType,dataType);PlanData planData=new Pla
31、nData();planData.setYeraPlanList(getYearPlanList (paramObj);planData.setLastYeraPlanList(getLastYearPlanList (paramObj );編輯課件重構(gòu)方法介紹:引入?yún)?shù)對象重構(gòu)方法介紹:引入?yún)?shù)對象(3)l你常會看到特定的數(shù)組參數(shù)總是一起被傳遞。可能有好幾個函數(shù)都使用這一組參數(shù),這些函數(shù)可能隸屬同個class,也可能隸屬不同的classes。這樣一組參數(shù)就是所謂的data Clump(數(shù)據(jù)泥團(tuán)),我們可以運(yùn)用一個對象包裝所有這些數(shù)據(jù),再以該對象取代它們。哪伯只是為了把這些數(shù)據(jù)組織在一起,這樣
32、做也是值得的。本項(xiàng)重構(gòu)的價(jià)值在于縮短了參數(shù)列的長度,而你知道,過長的參數(shù)列總是難以理解的。此外,新對象所定義的訪問函數(shù)還可以使代碼更具一致性,這又進(jìn)一步降低了代碼的理解難度和修改難度。l本項(xiàng)重構(gòu)還可以帶給你更多好處。當(dāng)你把這些參數(shù)組織到起之后,往往很快可以發(fā)現(xiàn)一些可被移至新建class的行為。通常,原本使用那些參數(shù)的函數(shù)對那些參數(shù)會有一些共通措施,如果將這些共通行為移到新對象中,你可以減少很多重復(fù)代碼編輯課件重構(gòu)方法介紹:函數(shù)遷移重構(gòu)方法介紹:函數(shù)遷移(1)(1)public class RepUtilFunc private List initFundList().this.copyFund
33、View(fView,planView); /匯總投資計(jì)劃數(shù)據(jù)private void copyFundView (FundView fView,PlanView planView)fView.setFund(fView.getFund()+planView.getFund();fView.setUpprefund(fView.getUpprefund()+planView.getUpprefund();fView.setDownprefund(fView.getDownprefund()+planView.getDownprefund();public class RepUtilFunc p
34、rivate List initFundList().fView.copyFundView(planView); /匯總投資計(jì)劃數(shù)據(jù)編輯課件重構(gòu)方法介紹:重構(gòu)方法介紹:函數(shù)遷移函數(shù)遷移(2)(2)public class FundView private double fund;private String upprefund; private String downprefund;getset方法public class FundView private double fund;private String upprefund; private String downprefund;gets
35、et方法public void copyFundView (PlanView planView)this.setFund(this.getFund()+planView.getFund();this.setUpprefund(this.getUpprefund()+planView.getUpprefund();this.setDownprefund(this.getDownprefund()+planView.getDownprefund();編輯課件重構(gòu)方法介紹:重構(gòu)方法介紹:函數(shù)遷移函數(shù)遷移(3)(3)函數(shù)遷移是重構(gòu)理論的支柱。如果一個class有太多行為,或如果一個class與另一個c
36、lass有太多合作而形成高度耦合,我就會遷移函數(shù)。通過這種手段,我可以使系統(tǒng)中的classes更簡單,這些classes最終也將更干凈利落地實(shí)現(xiàn)系統(tǒng)交付的任務(wù)。常常我會瀏覽class的所有函數(shù),從中尋找這樣的函數(shù),使用另一個對象的次數(shù)比使用自己所駐對象的次數(shù)還多,就會進(jìn)行函數(shù)遷移。編輯課件重構(gòu)方法介紹:將過程化設(shè)計(jì)轉(zhuǎn)重構(gòu)方法介紹:將過程化設(shè)計(jì)轉(zhuǎn)換為面向?qū)ο笤O(shè)計(jì)換為面向?qū)ο笤O(shè)計(jì)l有時(shí)間的話用一個實(shí)際例子進(jìn)行展示。編輯課件四、測試驅(qū)動開發(fā)方法簡介四、測試驅(qū)動開發(fā)方法簡介測試驅(qū)動開發(fā)(Test Driven Development,英文縮寫TDD)是極限編程的一個重要組成部分,它的基本思想就是在開發(fā)
37、功能代碼之前,先編寫代碼的單元測試用例。也就是說在明確要開發(fā)某個功能后,首先思考如何對這個功能進(jìn)行測試,并完成測試用例的編寫,然后編寫相關(guān)的代碼滿足這些測試用例。循環(huán)進(jìn)行添加其他功能,直到完成全部功能的開發(fā)。代碼整潔可用(clean code that works) 是測試驅(qū)動開發(fā)所追求的目標(biāo)。編輯課件測試驅(qū)動開發(fā)優(yōu)點(diǎn)測試驅(qū)動開發(fā)優(yōu)點(diǎn)(1)(1)l需求向來就是軟件開發(fā)過程中感覺最不好明確描述、易變的東西。這里說的需求不只是指用戶的需求,還包括對代碼的使用需求。很多開發(fā)人員最害怕的就是后期還要修改某個類或者函數(shù)的接口進(jìn)行修改或者擴(kuò)展,為什么會發(fā)生這樣的事情就是因?yàn)檫@部分代碼的使用需求沒有很好的描
38、述。測試驅(qū)動開發(fā)就是通過編寫測試用例,先考慮代碼的使用需求(包括功能、過程、接口等),而且這個描述是無二義的,可執(zhí)行驗(yàn)證的。 l通過編寫這部分代碼的測試用例,對其功能的分解、使用過程、接口都進(jìn)行了設(shè)計(jì)。而且這種從使用角度對代碼的設(shè)計(jì)通常更符合后期開發(fā)的需求??蓽y試的要求,對代碼的內(nèi)聚性的提高和復(fù)用都非常有益。因此測試驅(qū)動開發(fā)也是一種代碼設(shè)計(jì)的過程。 l開發(fā)人員通常對編寫文檔非常厭煩,但要使用、理解別人的代碼時(shí)通常又希望能有文檔進(jìn)行指導(dǎo)。而測試驅(qū)動開發(fā)過程中產(chǎn)生的測試用例代碼就是對代碼的最好的解釋。 編輯課件測試驅(qū)動開發(fā)優(yōu)點(diǎn)測試驅(qū)動開發(fā)優(yōu)點(diǎn)(2)(2)l快樂工作的基礎(chǔ)就是對自己有信心,對自己的工
39、作成果有信心。當(dāng)前很多開發(fā)人員卻經(jīng)常在擔(dān)心:“代碼是否正確?”“辛苦編寫的代碼還有沒有嚴(yán)重bug?”“修改的新代碼對其他部分有沒有影響?”。這種擔(dān)心甚至導(dǎo)致某些代碼應(yīng)該修改卻不敢修改的地步。測試驅(qū)動開發(fā)提供的測試集就可以作為你信心的來源。 l當(dāng)然測試驅(qū)動開發(fā)最重要的功能還在于保障代碼的正確性,能夠迅速發(fā)現(xiàn)、定位bug。而迅速發(fā)現(xiàn)、定位bug是很多開發(fā)人員的夢想。針對關(guān)鍵代碼的測試集,以及不斷完善的測試用例,為迅速發(fā)現(xiàn)、定位bug提供了條件。 l我的一段功能非常復(fù)雜的代碼使用TDD開發(fā)完成,真實(shí)環(huán)境應(yīng)用中只發(fā)現(xiàn)幾個bug,而且很快被定位解決。您在應(yīng)用后,也一定會為那種自信的開發(fā)過程,功能不斷增加
40、、完善的感覺,迅速發(fā)現(xiàn)、定位bug的能力所感染,喜歡這個技術(shù)的。 編輯課件測試驅(qū)動開發(fā)基本過程測試驅(qū)動開發(fā)基本過程l明確當(dāng)前要完成的功能??梢杂涗洺梢粋€ TODO 列表。l快速完成針對此功能的測試用例編寫。l測試代碼編譯不通過。l編寫對應(yīng)的功能代碼。l測試通過。l對代碼進(jìn)行重構(gòu),并保證測試通過。l循環(huán)完成所有功能的開發(fā) 編輯課件測試驅(qū)動開發(fā)案例測試驅(qū)動開發(fā)案例(1)(1) 需求:實(shí)現(xiàn)Fibonacci數(shù)列Fibonacci數(shù)列簡介:Fibonacci數(shù)列從第0項(xiàng)開始依次為0,1,1,2,3,5,8的數(shù)列,它存在如下特點(diǎn):第0,1個數(shù)為0,1。從第2個數(shù)開始,該數(shù)是前面兩個數(shù)之和。 編輯課件測試
41、驅(qū)動開發(fā)案例測試驅(qū)動開發(fā)案例(2)(2) 先編寫測試代碼 : import junit.framework.TestCase; public class FibonacciTest extends TestCasepublic void testFibonacci() FibUtil fb = new FibUtil(); 編寫完測試代碼之后在Eclipse中運(yùn)行該測試類,發(fā)現(xiàn)Junit運(yùn)行出錯(顯示了一條紅色杠) 這是在預(yù)料之中,因?yàn)槲覀冞€沒有編寫FibUtil類。編輯課件測試驅(qū)動開發(fā)案例測試驅(qū)動開發(fā)案例(3)(3) 為了使測試通過,那么下面開始編寫FibUtil類public class
42、FibUtil 然后再次運(yùn)行測試類。這時(shí)會發(fā)現(xiàn)測試成功。 編輯課件測試驅(qū)動開發(fā)案例測試驅(qū)動開發(fā)案例(4)(4) 下面增加測試用例,開始測試Fibonacci數(shù)列的實(shí)現(xiàn)函數(shù)fib:public void testFibonacci() FibUtil fb = new FibUtil(); assertEquals(0,fb.fib(0); 由于出現(xiàn)編譯錯誤,所以需要在FibUtil類中增加fib方法如下:public int fib ( int i) return 0 ; 運(yùn)行測試用例,通過! 編輯課件測試驅(qū)動開發(fā)案例測試驅(qū)動開發(fā)案例(5)(5) 繼續(xù)增加測試用例,判斷1的情況:public void testFibonacci() FibUtil fb = new FibUtil(); assertEquals(0,fb.fib(0)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 合同管理培訓(xùn)合同:上海項(xiàng)目實(shí)踐與招投標(biāo)(2025版)
- 二零二五年度智慧城市建設(shè)名義合伙人合同3篇
- 2025年度農(nóng)民工勞動合同電子化管理方案及實(shí)施細(xì)則3篇
- 二零二五年度農(nóng)業(yè)產(chǎn)業(yè)鏈金融服務(wù)創(chuàng)新合同-@-1
- 2025版企業(yè)內(nèi)部設(shè)備維修承包合同規(guī)范文本4篇
- 2025年度排洪渠項(xiàng)目監(jiān)理合同模板3篇
- 二零二五年度人工智能核心算法軟件知識產(chǎn)權(quán)獨(dú)家轉(zhuǎn)讓合同3篇
- 二零二五年度全新品牌專賣店開設(shè)服務(wù)合同范本4篇
- 2025年度票據(jù)代理業(yè)務(wù)委托合同范本6篇
- 2025年度苗圃技術(shù)員崗位聘用合同修訂版
- GB/T 45107-2024表土剝離及其再利用技術(shù)要求
- 2024-2025學(xué)年八年級上學(xué)期1月期末物理試題(含答案)
- 商場電氣設(shè)備維護(hù)勞務(wù)合同
- 《妊娠期惡心嘔吐及妊娠劇吐管理指南(2024年)》解讀
- 2025年高考語文作文滿分范文6篇
- 2023年國家公務(wù)員錄用考試《行測》真題(行政執(zhí)法)及答案解析
- 全國教學(xué)設(shè)計(jì)大賽一等獎英語七年級上冊(人教2024年新編)《Unit 2 Were Family!》單元教學(xué)設(shè)計(jì)
- 2024智慧醫(yī)療數(shù)據(jù)字典標(biāo)準(zhǔn)值域代碼
- 年產(chǎn)12萬噸裝配式智能鋼結(jié)構(gòu)項(xiàng)目可行性研究報(bào)告模板-立項(xiàng)備案
- 【獨(dú)家揭秘】2024年企業(yè)微信年費(fèi)全解析:9大行業(yè)收費(fèi)標(biāo)準(zhǔn)一覽
- 醫(yī)療器械經(jīng)銷商會議
評論
0/150
提交評論