記一次返工以後記

記一次返工以後記

做者:Greyhtml

時間:2018-11-25java

原文地址: http://www.javashuo.com/article/p-qdnnwvha-cb.html數據庫

說明

以前作的功能, 又有新的需求了,原先的需求是支持某個類型的待辦審批,如今是要支持系統全部類型待辦的審批,雖然以前的代碼寫的很匆忙,比較「醜陋」,可是好在未出什麼bug,新需求來了之後,我本想乘此機會重構一下本身以前寫的比較醜陋的代碼,可是由於陸陸續續有插入進來的優先級更高的任務,因此這個新需求一直被hold住,最後有一週的時間來作這個需求,因爲要測試的流程比較多,並且建立流程的過程比較費時,爲了給測試預留多一些時間,我放棄了重構的念頭,先快速實現需求,在保證原有功能和新增需求沒有問題的狀況下,再一點點重構本身的代碼。服務器

原需求

有一個Web系統X,用戶能夠經過這個系統查看本身的待辦信息,而且能夠用於待辦的審批,還有一個咱們作的手機應用Y,Y系統須要支持查看X系統的待辦信息並完成審批操做。運維

新需求

原需求裏面說的待辦信息只是某兩個類型的待辦,實際上這個X系統有不少待辦類型,並且每一個類型的處理邏輯,顯示元素都是不同的,咱們如今要實現再Y上支持X系統的全部待辦類型的審批。工具

資源

  1. X系統的源碼。
  2. X系統雖然不是咱們公司作的,可是我司運維人員對於X系統的業務相對熟悉。

開發前的準備

爲了不上一次返工的問題之一:需求沒有梳理清楚。在寫代碼以前,開發和測試都須要很是瞭解業務邏輯,因此,在開發以前,我特地申請了一次培訓,讓運維人員給咱們(我做爲開發,還有一位測試人應)講解一下整個系統的流程,也不須要特別正式的會議室,就幾我的在電腦旁邊,運維人員從頭至尾給咱們整個走一遍流程,有任何疑問都當下提出,當下解決, 解決不了的記錄下來,運維人員後去請教實際用戶這些問題。補充一點:最瞭解X系統業務的人固然是使用這個系統的用戶,但是這個系統比較特殊的一點是,大部分用戶都是領導,咱們幾乎不太可能讓領導來花時間來給咱們講整個業務邏輯,只能是當咱們遇到一些實際的業務問題,再去和他們請教。而運維人員,算是除了用戶之外,相對比較瞭解X系統的人了,什麼?你說X系統的開發人員?這個系統的開發商已經「跑路」了:)測試

在培訓完業務流程後,我尚未急着作開發,而是先讓測試人員在X系統上走一遍流程,並把走流程中的一些關鍵信息(如待辦詳情,操做按鈕,下一步操做選擇)截圖,一來測試須要瞭解整個業務流程才知道如何設計測試用例,二來截圖也能夠給我開發作一些參考,好比須要顯示待辦詳情裏面的哪些信息,操做按鈕要如何顯示,下一步操做要如何處理等。this

測試人員在X系統上走完流程之後,我本身也參考測試人員寫的操做步驟和截圖,走了一遍流程,算是內心有個底了。設計

遇到的問題

X系統有個測試環境,咱們都是在X系統的測試環境中開發和測試的,可是這個環境很不穩定,由於運維人員常常爲了排查X系統的問題,會常常把X系統正式環境的數據導入到測試環境,這樣咱們在X系統作的數據就會被重置,這就尷尬了,咱們的開發週期是一週,想在這一週保證測試數據穩定是不可能的了,因此,我又作了一件事,找了一個新的服務器,在這個服務器上從新搭建一個X系統的測試環境(包括應用服務器,數據庫),總算是解決了這個問題。日誌

遇到的另一個問題是,每次X系統中的待辦建走到特定節點比較費時,而每一個特定節點須要定製開發,好比咱們的手機應用Y要支持X系統某個待辦的第五個環節,那我須要在X系統上建一個待辦,而後一步一步走到第五個環節,而後找這個環節須要顯示的信息,須要作的操做,很是麻煩,並且一旦我在手機上操做了這個環節(好比審批了),這個環節就跳到了第六個環節了,若是我第五個環節的東西尚未徹底開發完,我又要建一個流程並走到第五個環節,比較麻煩。因此我想了一個辦法,就是在走到某個環節的時候,先備份一下數據庫,走完這個環節若是想再回去看下的話,直接恢復備份數據庫就能夠了。

開發和測試

放棄重構想法之後,我開發相對比較謹慎,基本沒有改動以前的代碼,新的需求都是從新寫的代碼,併爲考慮複用太多以前的代碼,雖然幾回很想重構,可是仍是忍住了,求穩。

業務邏輯理清了,接下來就是要看懂X系統的源碼了,X源碼註釋也比較少,充斥着相似如下這樣的代碼:

if(StringUtils.equalsIgnoreCase(subTypeId, "501")){
    // do something
    ...
}else if(StringUtils.equalsIgnoreCase(subTypeId, "502")){
    // do something
    ...
}else if(StringUtils.equalsIgnoreCase(subTypeId, "601")){
    // do something
    ...
}else if(StringUtils.equalsIgnoreCase(subTypeId, "602")){
    // do something
    ...
} else if(StringUtils.equalsIgnoreCase(subTypeId, "604")){
    // do something
    ...
}

我必須一個一個節點走才知道這裏的諸如:"501","604"是什麼意思,而後把這裏面對應的SQL拿出來分析,看下須要哪些參數,這些參數是如何獲取的,並且有些SQL的查詢還很複雜,參數不少,我本想直接用正則匹配頁面中的這些參數值,後來想一想,仍是不能依賴X系統的頁面信息,我都是直接查數據庫獲取須要的參數,分析SQL和獲取查詢參數,耗費了巨大的時間,不過事實證實,這樣作是對的,我這至關於重作了一遍X系統了。

接下來是設計X系統集成到咱們手機APP系統Y中之後的展現和操做,因爲數據都拿到了,我就須要把這些數據轉換成咱們手機APP中展現的元素,好比:Table,KeyValue,List,這些東西實際上沒有一個統一的標準,咱們就把詳情中比較關鍵的一些信息顯示出來,至因而顯示成Table仍是KeyValue,這個沒有嚴格的標準,用戶彷佛不太關注內容的排版,只要是顯示了必要信息,簡單明瞭,就足夠了,因此這部分」設計「,就按照我本身的想法來作了。

接下來是審批操做,審批操做比較麻煩的一點是,你必須徹底瞭解,點擊這個待辦的操做按鈕背後的全部邏輯,由於咱們是要集成待辦的操做,因此咱們實現的邏輯要和X系統如出一轍,最簡單粗暴的方案固然是模擬X系統的操做,好比用一些爬蟲工具模擬點擊操做的按鈕,這樣咱們就徹底不須要了解X系統的操做流程了,可是這並不保險,仍是由於上一次返工給我帶來的教訓:萬一操做的元素變更了一下,咱們的操做就徹底失效了。因此此次我仍是選擇直接理解操做背後的邏輯,說白了就是把操做對應的Ajax請求一個一個看懂並找到對應的參數值,而後發一個如出一轍的Ajax操做,固然X系統點擊操做還不是簡單的拿一些現有的參數發請求,有一些是頁面中的js拼裝的一些數據,這部分也要徹底理解並徹底移植過來,一旦有一些操做沒有移植過來,若是待辦審批出了問題,是很是嚴重的,由於這些待辦涉及比較重要的招投標流程,流程涉及的金額也是很大的。

我回憶了一下,真正寫代碼的時間實際上很少,花時間最多的是看X系統的源碼,和熟悉X系統的業務流程。

最後是測試,由於要在手機APP上測試流程,可是咱們本身的工號下面都沒有對應的待辦信息,須要登陸相應的領導的帳戶才能夠拿到待辦信息,雖然是測試環境,可是咱們手機APP是不會用用戶的信息去登陸測試的,由於登陸後,用戶的全部信息咱們均可以看到了,解決辦法就是,在獲取用戶待辦的時候,咱們只拿用戶的X系統的待辦,其餘信息不獲取,因此獲取X系統的待辦邏輯的代碼,加了這麼一小段邏輯,大概意思就是以下:

this.工號 = 獲取登陸人的工號(); // 登陸人是本身人
Map<String,String> changedInfo = newHashMap();
changedInfo.put("本身人的工號1","有待辦的人的工號1");
changedInfo.put("本身人的工號2","有待辦的人的工號2");
changedInfo.put("本身人的工號3","有待辦的人的工號3");
this.工號 = changedInfo.get(this.工號);

List todoList = 經過工號獲取某人X系統的待辦信息(this.工號);

感悟

這個需求開發並上線已經兩週了,我監控了一段時間運行日誌,暫時未發現問題,本次整個開發過程,吸收了上一次返工的教訓,爲我之後的開發工做也積累了一些新的經驗,謹以這兩篇博客(本篇博客, 上一篇博客)做爲一個記錄,也但願能夠分享給有須要的人。

相關文章
相關標籤/搜索