新聞中心
選擇重寫:噩夢(mèng)的開始

在方正等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都外貿(mào)網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作按需求定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),成都營銷網(wǎng)站建設(shè),外貿(mào)網(wǎng)站建設(shè),方正網(wǎng)站建設(shè)費(fèi)用合理。
復(fù)雜繁多的應(yīng)用程序往往牽一發(fā)動(dòng)全身,當(dāng)你想重做部分應(yīng)用時(shí),發(fā)現(xiàn)其他的應(yīng)用程序也會(huì)受到影響。
更糟糕的是,當(dāng)你更改代碼前試圖編寫單元測(cè)試時(shí),發(fā)現(xiàn)該代碼最初并沒有設(shè)計(jì)成可測(cè)試的代碼。所以,在進(jìn)行了種種掙扎和嘗試后,你可能就會(huì)把這個(gè)應(yīng)用程序凍結(jié)起來,再也不想碰它了......
那么,有沒有一種辦法既能更改無法維護(hù)的代碼,又能使局面不那么糟糕呢?
我們知道,更改代碼存在一定風(fēng)險(xiǎn),而重構(gòu)成本又太高。在這種情況下,從頭開始重新編寫代碼看起來是個(gè)不錯(cuò)的主意。
按照這個(gè)思路,接下來會(huì)發(fā)生什么?
- 你在重寫現(xiàn)有應(yīng)用程序的同時(shí),與管理層討論一段時(shí)間內(nèi)停用新功能。
- 重寫一個(gè)包含現(xiàn)在 應(yīng)用程序 功能的新程序大約耗時(shí) 6 個(gè)月。
- 幾個(gè)月后,出現(xiàn)了一個(gè)令人討厭的 bug,并且這個(gè) bug 必須在舊代碼中修復(fù)。因此,你又修補(bǔ)了舊代碼和新代碼。
- 再過幾個(gè)月,公司將一些新功能交付給了客戶。但新功能必須用舊代碼才能實(shí)現(xiàn),因?yàn)樾掳姹旧形礈?zhǔn)備好。你不僅要再次返回到舊代碼中,還要添加一個(gè) TODO 以便這些新功能在新版本中實(shí)現(xiàn)。
- 轉(zhuǎn)眼 5 個(gè)月過去了,你意識(shí)到項(xiàng)目可能要延遲,舊應(yīng)用程序遠(yuǎn)比想象得要棘手。
- 7 個(gè)月過去了,你開始測(cè)試新版本,QA 質(zhì)量檢查發(fā)現(xiàn)了很多需要修復(fù)的問題。
- 9 個(gè)月后,公司再也受不了“不開發(fā)功能”。領(lǐng)導(dǎo)開始不滿,你為此身心俱疲。你一邊掙扎著更改舊代碼,一邊加快速度重寫代碼。
- 最終結(jié)果是,你做出了兩個(gè)系統(tǒng)。擺脫舊代碼還需要一段時(shí)間,因?yàn)樾麓a還沒準(zhǔn)備好。每個(gè)功能都需要在新系統(tǒng)和舊系統(tǒng)中實(shí)現(xiàn)兩次。
最終,我選擇扼殺
我現(xiàn)在的項(xiàng)目,就是在處理這個(gè)問題。我們內(nèi)部有兩個(gè)并行工作的系統(tǒng):cart(舊系統(tǒng))和 booking(新系統(tǒng))。實(shí)際上,booking 應(yīng)該替換掉 cart。
該項(xiàng)目始于三年前,但三年過去了,項(xiàng)目仍然未完成。
booking 總體上講要優(yōu)于 cart,但并不是說所有方面都比 cart 出色,一些購買流程會(huì)使用 booking,但仍有很多流程沿用 cart。
現(xiàn)在,由于新舊系統(tǒng)并行工作,所以新功能的實(shí)現(xiàn)時(shí)間是原來的兩倍。有趣的是,由于最初的設(shè)計(jì)目的并不是為了支持我們想要的新功能,而是因?yàn)?booking 有些過時(shí)了,所以才會(huì)建議“適當(dāng)重寫 cart 系統(tǒng)。”
如果按照這個(gè)思路,接下來幾個(gè)月,我們可能要讓兩個(gè)系統(tǒng)并行運(yùn)行。顯然,這不是個(gè)好辦法,我還知道另外一種能有效解決系統(tǒng)問題的辦法,就是“扼殺”。
如何“扼殺”舊代碼庫
方法很簡(jiǎn)單:逐步刪除舊的代碼庫,使用新的代碼庫。
具體操作如下:
- 讓新代碼充當(dāng)舊代碼的代理服務(wù)器(proxy)。用戶使用新系統(tǒng),新系統(tǒng)重定向到舊系統(tǒng)。
- 在新代碼庫重新實(shí)現(xiàn)每步操作,這種操作在終端用戶看來沒有任何變化。
- 通過讓用戶使用新功能來逐漸淡化舊代碼。刪除舊的、未使用的代碼。
實(shí)際操作
來說說我們的系統(tǒng),我們有一個(gè)用于處理付款的 cart模塊。
我們嘗試重寫,想法是創(chuàng)建一個(gè)新的、比 cart 更好的 booking 支付方式。但是這個(gè)項(xiàng)目沒有 100%交付,因?yàn)橹貙懝ぷ骱馁M(fèi)了太多時(shí)間,我們不得不在舊 cart 系統(tǒng)上開發(fā)新功能。
最終,我們還是創(chuàng)建了兩個(gè)模塊。
讓我們?cè)僭囈淮?,這次我們來“扼殺”cart 模塊。與上一種方式不同的是,這次我們引入新 booking 模塊作為代理服務(wù)器。
設(shè)置起來很容易。很快,我們可以在不重復(fù)付款處理邏輯的情況下將其交付生產(chǎn)。然后,逐步地,我們可以開始將付款邏輯遷移到新的 booking 模塊。
在遷移邏輯時(shí),我們擺脫了 cart 模塊上未使用的代碼。這個(gè)過程可能會(huì)需要一段時(shí)間,但我們正逐漸摒棄掉舊的、難以維護(hù)的 cart,開始應(yīng)用新的、更好的 booking。
結(jié)束語
這樣做最好的地方是可以解決重寫期間無法交付新功能的問題。使用這種技術(shù),無需復(fù)制代碼,更無需實(shí)現(xiàn)兩次新功能。另外,你需要盡快將新系統(tǒng)投入使用,更快地獲得反饋,很大程度減少工作量并且降低把事情搞砸的風(fēng)險(xiǎn)。
最后,你可以有條不紊地進(jìn)行重寫,而無需將代碼凍結(jié) 6 個(gè)月。盡管“扼殺”可能帶有暴力色彩,但這種隱喻恰恰描述了慢慢擺脫舊系統(tǒng)的方法,與完全轉(zhuǎn)換相比,這樣做的風(fēng)險(xiǎn)較小。當(dāng)舊代碼實(shí)在難以使用時(shí),這可能是邁向更好設(shè)計(jì)的第一步。
如果你在從事領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD),我建議你采用這種方法逐步淘汰舊系統(tǒng)。
你可以將舊系統(tǒng)視為黑匣子,創(chuàng)建一個(gè) Bubble Context ,在其中應(yīng)用部署 DDD 原理。Bubble Context 與舊系統(tǒng)進(jìn)行交互。逐漸地,新功能將在不斷增長(zhǎng)的 Bubble context 中實(shí)現(xiàn)。同時(shí),業(yè)務(wù)中用到舊系統(tǒng)的機(jī)會(huì)也越來越少,直到有一天,你可以徹底關(guān)閉舊系統(tǒng)。
本文標(biāo)題:換血!重寫舊系統(tǒng)的一場(chǎng)噩夢(mèng)被我親手終結(jié)
網(wǎng)頁網(wǎng)址:http://m.5511xx.com/article/dpgoipp.html


咨詢
建站咨詢
