從軟體遺產到策略機會:起點(一)
重建遺留軟體:從挑戰到機會
本文講述了我們如何處理一個物流管理系統(OMS)的國際化,以及與新的電子商務平台整合的挑戰。該系統開發於2018年,旨在優化一個蓬勃發展的電商的訂單準備流程,並與不同的物流運營商高效整合。它使用PHP(Symfony)、MySQL、Socket.io和jQuery構建,涵蓋從包裝到發貨的整個流程,包括訂單追蹤、快遞員連接、標籤生成和訂單準備性能指標等功能。
技術債的累積
多年來,該系統運作良好,但隨著業務發展,其限制日益顯現。技術債尤其令人擔憂,它影響了專案的多個層面。在技術基礎設施方面,該應用程式運行在過時的框架和基礎語言版本:
- Symfony版本(4.0)並非長期支援(LTS)版本,自2019年1月起停止接收安全更新。
- PHP 7.1也已結束生命週期,系統缺乏關鍵的安全性更新。
除了過時的版本,專案在軟體開發的基礎方面也存在嚴重缺陷:
- 缺乏或不足的測試: 缺乏自動化測試(單元測試、整合測試和端到端測試)不僅阻礙了早期錯誤的發現,還使任何修改都可能危及系統的穩定性。
- 缺乏程式碼標準: 程式碼庫沒有遵循任何已記錄的模式或標準,即使有,也與業界最佳實踐不符。這使得維護和專案中新開發人員的加入都變得困難。
- 文件不足: 現有文件稀少且經常不完整。這不僅影響了技術開發,也影響了對程式碼中實現的業務流程的理解。
- 版本控制不完善: Git歷史記錄缺乏解釋,提交粒度粗糙,訊息也不遵循任何約定,缺乏對所做更改的背景資訊。這使得理解程式碼的演變和隨時間做出的決策變得困難。
技術債的累積不僅對系統的穩定性和安全性構成威脅,還:
- 降低了新功能的開發速度
- 增加了引入錯誤的風險
- 增加了新成員加入團隊的難度
- 增加了維護成本
- 讓問題診斷與解決變得複雜
結構性限制
最初的架構存在耦合問題,嚴重影響了其靈活性和可擴展性:
- 完全依賴主電商平台: 該應用程式無法獨立運行,所有物流操作都直接依賴電商平台的數據和流程。這意味著主平台的任何變更都可能破壞系統的功能。
- 共享資料庫導致效能問題: 物流應用程式和電商平台使用相同的資料庫,這導致效能問題,尤其是在任一應用程式的負載高峰期。此外,此配置使權限管理變得複雜,因為對資料庫的任何存取都可能危及其他系統的重要資料。
- 無法獨立運作: 該應用程式的設計只能與電商平台一起運作。這不僅限制了其可移植性,還阻礙了在隔離環境中進行測試或遷移到其他平台。其依賴項沒有適當的封裝,任何隔離嘗試都需要對整個系統進行大規模且代價高昂的更改,主要類別中沒有遵守單一責任原則(SRP)。
- 難以實現新功能: 缺乏對開放/封閉原則(OCP)和Liskov替換原則(LSP)的遵守,極大地阻礙了系統的演進。新功能需要修改現有程式碼,增加了引入迴歸的風險。此外,模組之間的直接依賴使得遵循依賴倒置原則(DIP)幾乎不可能。
這些結構性限制不僅降低了系統的可維護性和可擴展性,還增加了與任何修改或演進相關的風險,使應用程式處於技術上脆弱和戰略上易受攻擊的狀態。
開發管理與策略一致性
最顯著的挑戰之一不僅是技術性的,也是策略性的。儘管外部開發在功能上是正確的,但在組織方面存在重大限制:
- 與全球策略脫節: 開發是孤立進行的,沒有對公司內部目標和流程的完整了解。這導致了一些功能,儘管技術上是正確的,但並非總是符合業務的實際需求。
- 缺乏策略優先事項: 新功能的實施缺乏明確的評估和優先排序流程。沒有質疑一個功能是否真正必要,是否是最佳實現方式,或者是否有更有效的替代方案。
- 被動式開發 vs. 主動式開發: 開發主要遵循被動模式,解決直接需求,而沒有考慮長期影響或與公司其他流程的潛在協同作用。
- 缺乏驗證流程: 缺乏結構化的審查和驗證流程導致了一些功能,儘管可以運行,但並不總是對最終用戶或公司的整體目標提供最佳解決方案。
這種情況在長期內是不可持續的,因為它:
- 導致產品越來越偏離實際需求
- 阻礙了與公司其他系統和流程的整合
- 讓關於產品的策略決策變得複雜
- 限制了團隊的創新和持續改進能力
基本成本的影響
在本專案中,一個經常被忽視但特別重要的方面是基本成本,我認為這是軟體開發中的一個關鍵概念,它指的是即使不添加新功能或進行改進,維持系統運作所需的最低成本。
在我們的案例中,基本成本包括所有因需要維護過時的框架和語言版本、解決因技術債務累積而導致的緊急事件、管理與其他系統的依賴關係、適應耦合的架構以及對領域知識的了解不足而產生的費用。所有這些都消耗了大量可用資源,直接影響了投資創新和持續改進的能力。
雖然這個因素並不是促使我們決定內部化開發的決定性因素,但在專案的初步診斷中,它具有相當大的影響力。基本成本通常在評估系統的可持續性時被忽略,但在本案例中,它清楚地表明當前的策略在長期內是不可持續的。此外,正如我們在後續文章中將看到的,任何試圖維持現有結構的嘗試都將隨著時間的推移成倍地增加基本成本。
有關基本成本概念及其重要性的更詳細解釋,建議參考Eduardo Ferro的原始文章。
轉捩點:新的挑戰與策略決策
在任何重建項目中,都可以採用多種策略,並且經常會遇到以下兩難:絞殺者模式(strangler fig)或徹底重寫(big bang rewrite)。
最初的技術決策是在同一個遺留項目中工作,採用絞殺者模式,這種方法包括開發一個新的模組或系統,逐步替換舊系統的部分。這種策略允許我們進行並行更改,降低風險,並在建立更堅實的基礎以支援未來功能的同時保持當前功能。
然而,從業務的角度來看,這種選擇對現有系統(該系統已投入運作並履行其職能)構成了過高的風險。我們決定避免觸碰現有項目,而是開發一個獨立的應用程式來滿足新的需求。
這種轉變導致我們對現有程式碼庫進行了分支,這是一個技術上可行但存在某些缺點的決定:
- 程式碼庫的重複:現在需要維護兩個單獨的程式碼庫。
- 資料庫分離:必須為每個系統複製和調整資料結構。
- 基礎設施複製:需要部署獨立的伺服器並為每個系統保證適當的可觀察性。
- 團隊的認知負擔增加:所有這些重複都需要額外的努力來維護兩個系統之間的一致性,從而增加了團隊的複雜性和錯誤風險。
這種方法使我們能夠朝著獨立的解決方案前進,確保現有系統的穩定性,同時開發一個與新的策略目標一致的專案。然而,必須詳細分析利弊,才能充滿信心地進行規劃和應對這項挑戰。此外,我們與業務層面達成了共識,即不擴展功能,並在完成向新電子商務平台的遷移之前嚴格控制專案的積壓工作。
优点 | 缺点 |
---|---|
在非生产环境中工作,降低生产环境的风险 | 需要暂时维护多个项目 |
自由地从零开始实施新技术和模式 | 在维护方面的努力暂时重复 |
不必担心旧系统的技术限制或依赖关系 | 由于需要在系统之间同步更改,功能的重复可能会长期减缓开发速度 |
能够专注于必要的特性 | 截止日期的风险,因为有两个代码库 |
有机会从一开始就实施最佳实践 | 项目管理的复杂性 |
更容易从一开始就实施测试 | 需要与历史数据保持兼容性 |
灵活地适应新的业务需求 | 初始时间和资源成本更高 |
更好地与公司的整体战略相一致 | 可能暂时丢失非必要的特性 |
結論與後續步驟
決定內部化和重寫遺留軟體從來都不是一件容易的事,尤其是在該軟體能夠完成其功能的情況下。 「如果它能工作,就不要碰它」這句話將始終存在。然而,有時需要後退才能前進兩步。
在本系列的後續文章中,我們將探討我們如何應對這些挑戰,我們所做的技術和策略決策,以及我們如何將這些挑戰轉化為改善和團隊發展的機會。
以上是從軟體遺產到策略機會:起點(一)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

會話劫持可以通過以下步驟實現:1.獲取會話ID,2.使用會話ID,3.保持會話活躍。在PHP中防範會話劫持的方法包括:1.使用session_regenerate_id()函數重新生成會話ID,2.通過數據庫存儲會話數據,3.確保所有會話數據通過HTTPS傳輸。

在PHP中,異常處理通過try,catch,finally,和throw關鍵字實現。 1)try塊包圍可能拋出異常的代碼;2)catch塊處理異常;3)finally塊確保代碼始終執行;4)throw用於手動拋出異常。這些機制幫助提升代碼的健壯性和可維護性。

PHP中有四種主要錯誤類型:1.Notice:最輕微,不會中斷程序,如訪問未定義變量;2.Warning:比Notice嚴重,不會終止程序,如包含不存在文件;3.FatalError:最嚴重,會終止程序,如調用不存在函數;4.ParseError:語法錯誤,會阻止程序執行,如忘記添加結束標籤。

在PHP中,include,require,include_once,require_once的區別在於:1)include產生警告並繼續執行,2)require產生致命錯誤並停止執行,3)include_once和require_once防止重複包含。這些函數的選擇取決於文件的重要性和是否需要防止重複包含,合理使用可以提高代碼的可讀性和可維護性。

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

HTTP請求方法包括GET、POST、PUT和DELETE,分別用於獲取、提交、更新和刪除資源。 1.GET方法用於獲取資源,適用於讀取操作。 2.POST方法用於提交數據,常用於創建新資源。 3.PUT方法用於更新資源,適用於完整更新。 4.DELETE方法用於刪除資源,適用於刪除操作。
