標籤:
這個套系統算是非常完整的,由我自己全程設計構建的系統。其他幾套系統多多少少是與同事合作之類的,並沒有那麼完整的經驗。
不算大的一套東西,但是卻的確學到很多,主要是關於資料庫設計、設計api、代碼結構設計、項目推進、項目時間和難度的預估、測試預估。
項目從拿到需求到積分系統的完成(包括對接現有支付模組,編寫測試之類)其實耗時不多,大概在16個天,對賬系統包括測試做了4天總工作日大概在20天。但是這個看似正常的時間,跟最開始估計的時間相差甚遠。我在前期有很多加班包括周末加班的情況下才勉強能照著現在這個進度完成,實際上最初估沒有對賬系統的完成時間只有12天,中間差了4個工作日,算上加班的時間可能差了7個工作日。可能這就是不經常預估項目時間的人容易犯下的錯誤吧,對自己的編碼效率莫名自信,殊不知裡面其實有大量不可控因素影響進度。其中很大影響比重在於修改前面人寫的支付模組的代碼上,不僅需要大量時間閱讀前面的人寫的代碼和思路,還需要把自己的邏輯加進去,這極花時間。所以估時間的時候一定要預留充足的時間,這個後面再提一下。
(一) 還是按順序來吧,先說資料庫設計,設計API,設計代碼結構
花了大概兩天時間設計了資料庫,一共涉及到11張表。弄好了之後拉著leader和主管開了一個短會,我闡述了我的設計思路,然後拉著他們幫我看看設計是否存在問題,或者有沒有地方有漏洞是我沒有辦法考慮到的。這裡我其實設計了兩張流水表,每當有一筆收入或者支出的積分,都會在支出和收入的流水表裡面增加一條記錄,但是最開始的時候,因為某些原因我可能需要update流水表裡面的欄位,但是leader告訴我流水表最好不要有update的操作,這樣可能比較容易出錯,流水表只往內記錄,不更新,這樣不會出問題。這點使得我開始從表穩定性去思考這個問題,覺得還是有一定道理。因為流水表最終在結算的時候可能用於對賬,一旦這個表因為更新欄位出現問題,那麼對賬就會出錯,電商系統的對賬出錯的話。。。。。
找前輩幫忙看因為他們比我更熟悉系統,所以一定要拉他們幫自己看看,否則有些坑,或者以前弄的hack可能會影響到新的系統進行某些操作。做了一些改動,然後我們一致同意了一個決定,就是如果全部做好一起上線代碼量超大最少2k行,可能完全沒有辦法review。畢竟要花時間去看一個2k行代碼的項目,還是需要花費不少的時間。所以決定將項目拆成兩塊分批上線。由於構件積分的查詢儲存使用之類的東西是完全不會影響到現有系統的,所以可以單獨上線,然後將接入現在的支付退款系統作為另外一部分進行上線。這樣就拆開了現在邏輯和新構件系統的耦合,看代碼上面也會變得稍微方便一些。
當時討論完之後,leader讓我最好當天的下午,或者第二天的早上將這套東西要提供給app的api定出來,大概需要哪些api。api定下來之後,寫東西就可以按照api來依次實現功能了。
這個步驟真的是讓我大受啟發,在資料庫設計完成之後,就設計到底要提供哪些功能出來,就能完成初步的api設計。這樣想就可以安好想提供的功能依次編寫代碼了,也不容易漏掉什麼東西。其實這裡面最難的部分,就是將思路理清楚,能讓自己知道究竟有哪些工作完成,什麼先完成,什麼可以後完成比較好。在設計完api和資料庫之後我可能需要畫一些圖,和做一些筆記來輔助我思考這些問題才可以讓我自己的思路變得更清晰。我自己的畫拿了幾張a4紙在上面大概畫了寫了一下有哪些api,名字大概叫什麼,提供什麼樣的功能,可能會設計到的表之類。
最後這個chapter裡面關於代碼結構:
dao裡面存放了各建立表的模型,由於使用orm所以使用到這些模型。
model裡面存放了各種中間邏輯,包括調用dao裡面的方法建立更新刪除資料,拼接各類資料。
外面api提供了各功能的api函數,api層我只處理了入參,保證各入參的類型合法然後傳給model對應的函數進行進一步的邏輯處理。
const裡面存放了各種可能會使用到的常量。在設計常量存放的時候這次踩了一個坑,最好把有哪幾個可能出現的常量類型分別建立一個類,在類下面寫,而且最好提前分配好他們所屬的數字地區。打個比方,我們可能有支出和收入不同的常量需求,千萬不要寫成這種:
class IncomeConst(object): INCOME_NORMAL_REVIEW = 1 # 正常評價獲得積分 INCOME_REVIEW_BONUS = 2 # 好評獲得的額外積分 INCOME_UNLOCK_ORDER = 5 # 訂單積分解除鎖定 INCOME_REFUND_ORDER = 7 # 退款退積分class ExpenditureConst(object): EXPENDITURE_FRESH_MEMBER = 3 # 愛嘗鮮購買 EXPENDITURE_LOCK_ORDER = 4 # 訂單積分消費鎖定 EXPENDITURE_OFFSET_CASH = 6 # 積分抵現
應該首先確定income裡面佔用的是1-1000的數字 那麼expenditure就可以佔用2-2000的數字 這樣能保證同樣類型的const是連貫的就像這樣:
class IncomeConst(object): INCOME_NORMAL_REVIEW = 1000 # 正常評價獲得積分 INCOME_REVIEW_BONUS = 1001 # 好評獲得的額外積分 INCOME_UNLOCK_ORDER = 1002 # 訂單積分解除鎖定 INCOME_REFUND_ORDER = 1003 # 退款退積分class ExpenditureConst(object): EXPENDITURE_FRESH_MEMBER = 2001 # 愛嘗鮮購買 EXPENDITURE_LOCK_ORDER = 2002 # 訂單積分消費鎖定 EXPENDITURE_OFFSET_CASH = 2003 # 積分抵現
不要把自己搞得像個精神分裂一樣,遇到了就往裡加一項數字上漲一個。。。。簡直不忍直視= =。
exception裡面存放了各種可能會拋出的錯誤,統一繼承自Excepition類
(二) 項目推進
項目推進的過程中,無非是按照前面設計好的東西按部就班的一個模組一個模組的寫。其實中間也沒有碰到什麼特別坑爹的事情,只是把原先的兩個上線步驟拆成了三個,因為發現前面其實雖然沒有構建整套積分支付的東西,但是卻有記錄使用者積分的東西,在使用者評論商品之後會給使用者記錄積分的,這就造成了前面多多少少寫了一些積分的東西,我需要把這些原有的東西分好類重新放回到積分新設計的積分模組裡面去。這一步其實我在估時間的時候沒有想到的,由於前面寫的代碼比較隨便,導致我遷移起來很費勁,有非常多的依賴滿天飛,多花了很多時間,而且是影響線上的東西不得不小心翼翼,測了又測。總結了一個經驗,先從依賴最少的地方開始拆,拆完一塊就測一塊。這樣一步一步的弄幾乎不會出錯。千萬不要一連遷好幾塊的東西,最後再來一起測,那個時候要是再測出了問題,我相信改起來的難度非常大。你要依次去排查是前面哪個改動導致了這個問題,這幾乎的是不可行的。
遷移的理想狀態是,所有東西都有單元測試,如果沒對的情況下,跑單元測試都會報錯,你就能及時發現並切改動。現實是(好殘酷的樣子),如果沒有單元測試,你可能需要穩健的一步一步來。當你把簡單的東西都遷走之後,你會發現之前那些難以遷移的東西也變成容易遷的東西了。
(三) 項目進度預估,對項目時間包括測試部分的預估
就像第一部分談到的,其實如果時間非常充足和從容,你可能有大把時間來按照我上面說的流程對關鍵區段進行仔細測試,甚至給每個地方都帶上單元測試。現實是如果你自己估的項目時間過短,你可能沒有時間來完善測試方面的事情。前提是你的公司裡面沒有專職QA,測試幾乎需要你自己完成,這個時候,將測試時間估算進你項目進度顯得非常重要。我這次的測試時間大概占完成項目時間的30%,這個結果很大部分取決於我還用了不少業餘時間完成項目或進行測試,以及依賴一些以前同事編寫的支付部分的測試,如果全部自己來的話我估計時間至少需要估完成項目時間的50%時間用於測試或者編寫單元測試。也就是說如果你估計這個項目你15天可以寫完,你可能大概需要額外的7天時間用於測試和修複測試出來的bug,以及自己對代碼二次review。這樣的進度才能保證你代碼的品質,以及在上線之後不用提心弔膽是否會被用戶端或者web端的同事找麻煩。
對時間方面的估算,沒有幾個項目的經曆是肯定估不準的,在你發現在deadline之前完成不了項目的時候,一定要向自己的leader說明項目延期,以及因為什麼原因導致了項目延期,並且儘快完成項目。所以對項目推進節奏的把控,可能嚴重影響項目品質,既不可以完全沒有壓力和時間上的deadline隨意完成項目,也不可把項目時間卡得過於緊,因為中間除了我上面分析得問題,還又可能出現諸如你需要請假有事,中途任務的插入。
以上。
電商積分支付系統構建經驗與總結