Code rant: 從硬編碼到可配置、規則引擎、低程式碼DSL的複雜性時鐘
當我還是一個年輕的程式設計師,剛剛開始進入企業軟體這個可怕的世界時,一個年長的、更有經驗的小夥子對我在軟體中硬編碼hardcode的做法提出了嚴厲的警告。"硬編碼會在某些時候被改變,你肯定不想為了改變某個增值稅稅率值而重新編譯和部署你的應用程式。”
我把這個建議記在心裡,很快我的應用程式需要的每一個值都必須從一個巨大的.ini檔案中載入。我仍然認為這是一個很好的建議,但是請注意,就像軟體中的大多數事情一樣,它在一定程度上是個好建議。超過這一點就會有痛苦。
讓我向您介紹我的“配置複雜性時鐘”:
這個時鐘講述了一個故事。我們從午夜12點開始,有一個簡單的新需求,我們迅速將其編碼為一個小應用程式。它不會持續很久,只是某個更大的戰略計劃中的一個權宜之計,所以我們硬編碼了所有的應用程式的值。幾個月過去了,這個應用程式被廣泛使用,但有一個問題,一些業務數值發生了變化,所以我們發現自己需要重寫構建和部署,就只是為了改變幾個數字。這顯然是錯誤的。解決辦法很簡單,我們將這些值移出到一個配置檔案中,也許是我們App.config中的一些appsettings,現在我們的時間是2點。
時間過去了,我們的應用程式現在在我們的組織中已經有些根深蒂固了。業務繼續發展,隨著它的發展,更多的值被移到我們的配置檔案中。現在appsettings已經不夠用了,我們有了值的組和值的層次結構。如果我們做得好的話,現在我們已經把我們的配置移到了一個專門的XML模式中,並被反序列化為一個配置模型。如果我們不是那麼好,我們可能已經把重複的和多維的值塞進了一些奇怪的管道分隔的字串中,現在我們的時間是4或5分鐘。
更多的時間過去了,那個令人討厭的 "首席軟體架構師 "被解僱了,我們的小應用程式現在是我們組織的核心。
業務規則變得越來越複雜,我們的配置也是如此。
事實上,在新員工能夠成功進行部署之前,有一個相當大的學習曲線。我們的一個新員工是個非常聰明的傢伙,他以前就見過這種情況。他說:"我們需要的是一個業務規則引擎"。現在這看起來很有希望。
配置從XML檔案轉移到資料庫中,並有自己專門的GUI。
起初,人們希望非技術性的業務使用者能夠使用GUI來配置應用程式,但事實證明這是一個錯誤的希望;將商業規則對映到引擎中需要一定程度的專業知識,而這隻有開發團隊中的一些成員才擁有。我們現在是在6點鐘。
令人沮喪的是,仍有一些業務需求無法使用新的規則引擎進行配置。
一些邏輯條件根本無法使用GUI進行配置,因此應用程式必須重新編碼併為一些場景重新部署。幫助就在眼前,團隊中有人讀了Ayende的DSL書。是的,DSL可以讓我們寫出任意複雜的規則,解決我們所有的問題。團隊停止了幾個月的工作來實現DSL。當它完成時,這是一個相當大的技術成就,每個人都好好休息了一下。當然,這將意味著任意的硬編碼業務邏輯的結束?現在是上午9點的時間。
令人驚訝的是,它還能工作。幾個月過去了,核心應用程式不需要任何改變。團隊花了大部分時間在新的DSL上寫程式碼。在經歷了一些尷尬的事件之後,他們現在在部署任何新的DSL程式碼之前都會經歷一個完整的釋出週期。DSL文字檔案是受版本控制的,每個版本在部署前都要經過迴歸測試。除錯DSL程式碼很困難,幾乎沒有工具支援,他們根本沒有資源為他們新的小語言建立一個IDE或ReSharper。隨著DSL程式碼變得越來越複雜,他們也開始懷念能夠編寫物件導向的軟體。團隊中的一些人已經開始在業餘時間研究單元測試框架。
在下班後的酒吧裡,有人打趣說:"我們又回到了四年前開始的地方,硬編碼的一切,只是現在用的是更蹩腳的語言。"
他們已經走了一圈,又回到了12點。
總結
為什麼要講這個故事?說實話,我從來沒有見過一個組織一路走來,但我見過很多人走到5、6或7的時候都感到相當痛苦。我的觀點是這樣的。
在一定的複雜程度上,硬編碼的解決方案可能是最不邪惡的選擇。
你已經有了一種通用的程式語言,在你建立一個業務規則引擎或DSL之前,或者即使你的配置通過了一定的複雜程度,考慮到有一個更靈活的構建-測試-部署週期,硬編碼可能要簡單得多。
當你按順時針方向走的時候,技術實現會變得越來越複雜。建立一個好的規則引擎是很難的,而編寫一個DSL則更難。順時針每多走一個小時,就會導致軟體更加複雜,出現更多的錯誤,而且新員工的學習曲線也會更加艱難。配置越複雜,在部署前就需要更多的控制和測試。很快你就會發現,在改變一行程式碼和改變一行配置之間所需的時間長度沒有什麼區別。你發現你的組織依賴於一種非常罕見的技能,而不是一種常見的技能,比如說編碼C#,你發現你的組織依賴於一種非常罕見的技能:理解你的規則引擎或DSL。
我並不是說實施複雜的配置、規則引擎或DSL是不合適的,事實上,如果有合適的要求,我也會抓住機會建立一個DSL,但我是說,在你走這條路之前,你應該理解其中的含義,並認識到你在時間上的位置。
相關文章
- 實戰複雜低程式碼專案React從架構到拆解React架構
- 開源規則引擎——ice:致力於解決靈活繁複的硬編碼問題
- 規則引擎整合新的可觀測性框架框架
- 降低程式碼的圈複雜度——複雜程式碼的解決之道複雜度
- Protobuf編碼規則
- 從0到1編寫一個指令碼引擎指令碼
- HAP_編碼規則
- 低程式碼-業務流程引擎
- 編寫可閱讀的程式碼--基本規約
- Flutter編譯時生成程式碼之 code_builderFlutter編譯UI
- 從0到1編寫一個JS指令碼引擎JS指令碼
- 什麼是低程式碼(Low-Code)?
- 複雜風控場景下,如何打造一款高效的規則引擎
- 程式設計師是如何從複雜的程式碼裡找到 bug 的?程式設計師
- 基於Groovy的規則指令碼引擎實戰指令碼
- 低程式碼開發平臺 讓資料應用不再複雜
- 前端開發越發複雜,你是否需要低程式碼平臺?前端
- 硬之城攜手阿里雲Serverless應用引擎(SAE)打造低程式碼平臺阿里Server
- 計算機編碼規則之:Base64編碼計算機
- 規則引擎在IoT的重要性?
- 編寫可讀性程式碼的藝術--萬字總結,看到即學到
- Android 程式碼混淆規則Android
- UTF-8編碼規則(轉)
- 主資料之編碼規則
- 體面編碼之命名規則
- SQLServer的排序規則(字符集編碼)SQLServer排序
- VS Code 程式碼片段指南: 從基礎到高階技巧
- Java語言編碼規範(Java Code Conventions)Java
- 什麼是低程式碼?一分鐘瞭解低程式碼「建議收藏」
- git管理複雜專案程式碼Git
- 知物由學 | 端遊程式碼保護:從原生程式碼到遊戲引擎遊戲引擎
- 淺析程式碼圈複雜度及認知複雜度複雜度
- 複雜多變場景下的Groovy指令碼引擎實戰指令碼
- 從鴻星爾克“出圈”看國產低程式碼平臺的時代性機遇
- 風控規則引擎(一):Java 動態指令碼Java指令碼
- Spring Boot中實現規則引擎原始碼教程Spring Boot原始碼
- 密碼的複雜化密碼
- 從零開始編寫指令碼引擎指令碼