




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