系統的混亂並非業務本身之複雜,我們並不擅長處理『簡單』

来源:https://www.cnblogs.com/88223100/archive/2023/01/21/We-are-not-good-at-dealing-with-simplicity.html
-Advertisement-
Play Games

一群高智商青年在餐廳吃飯,餐桌上一個瓶蓋標識為鹽的瓶子里裝得是胡椒粉,而標識為胡椒粉的瓶子里裝得卻是鹽,他們想出了一個充滿才氣的方案來完成對調--僅需要一張餐巾紙、一根吸管和兩個空碟子。當他們叫來服務員,準備炫耀他們的天才想法時,只見服務員什麼也沒說,只是拿起鹽瓶和胡椒粉瓶,互換了瓶蓋…… 在我們... ...


前言

一群高智商青年在餐廳吃飯,餐桌上一個瓶蓋標識為鹽的瓶子里裝得是胡椒粉,而標識為胡椒粉的瓶子里裝得卻是鹽,他們想出了一個充滿才氣的方案來完成對調--僅需要一張餐巾紙、一根吸管和兩個空碟子。當他們叫來服務員,準備炫耀他們的天才想法時,只見服務員什麼也沒說,只是拿起鹽瓶和胡椒粉瓶,互換了瓶蓋…… 
在我們軟體工程中,同樣一件事情可以有很多種解決方案,我們翻開那繼承下來的祖傳代碼,系統堆疊了太多它不需要或者它不適合的動態擴展、規則引擎、條件分支等等。原本並不複雜的業務最終得到的還是一片混亂,是我們的做法還是太過簡單嗎,或許本質上是我們並不擅長處理『簡單』。

 

本質複雜度與偶然複雜度

All software construction involves essential tasks and accidental tasks.
-- Frederick P.Brooks,Jr 《No Silver Bullet》
譯:所有軟體構建都包含其本質部分與偶然部分。

業務的複雜

Frederick P.Brooks,Jr 在1975年寫下了軟體界的一本著作 The Mythical Man-Month,國內也巧妙的譯為人月神話。書中提到軟體的複雜度包括本質複雜度和偶然複雜度。本質複雜度就是在解決問題時,無論如何都必須要面對的複雜度;而偶然複雜度,是由於選用的做事方法不當,導致額外增加的複雜度。
我們不否認在交易場景、訂單場景、支付場景等,可能天然存在非常複雜的業務邏輯,但同樣也並非所有的系統都像淘寶天貓一樣複雜。隨著業務的分拆,組織職能的劃分以及微服務的普及,我們面臨的問題與場景越來越小越來越聚焦。業務的複雜性天然存在,當我們看著那捉摸不透宛如天書的功能代碼時,我們試問一下自己的業務是否真的有那麼複雜。

 

系統的混亂

Despite all their heroics, overtime, and dedication, they simply aren't getting much of anything done anymore. All their effort is now consumed with managing the mess.
-- Robert C.Martin 《Clean Architecture》
譯:不管你們多敬業、加多少班,在面對爛系統時,你仍然會寸步難行,因為你大部分的精力不是在開發需求,而是在應對混亂。 
我們經常遇到一個簡單的業務訴求,但在老系統上支持就異常艱難。“在人離開的時候,自動把門關上”,但你永遠不知道這個房間到底有多少門,同樣你也莫名其妙會遇到,某些門關上後窗又碎了。
軟體工程最大的成本在於維護,系統的混亂並非業務本身之複雜,簡單的模塊我們同樣可能搞砸。為了未來可擴展,為了未來更靈活,我們不斷YY著所謂的未來,卻讓現在越來越糟。

 

我們以複雜應對簡單

訴求有時非常簡單,但我們又豈會“甘於做一個執行器”,我們認為這背後一定有更深刻的業務訴求,一定有更本質的商業問題,一定有更底層的層次邏輯。於是我們擺擺手說道:這可沒那麼簡單~

TMF的擴展實現

TMF是業務中臺面向可復用可擴展架構的核心,在平臺與業務分離,業務與業務隔離上可以起到重要作用。當我們發現有中國商家需求的同時還存在在海外商家業務,我們立馬抄起了TMF來設計我們的擴展與編排。最終代碼上線3年,也只有可憐的2個實現。無數的後人需要花更多的時間來理解與維護這段曾經的“高光設計”。 
當出現第3個擴展訴求時,有人發現不應該用這麼重的框架,於是寫了一個簡單的策略模式來支撐,而原有的TMF代碼又不敢動,於是在可憐的3個擴展實例里還並存著2套擴展框架。再接下來又引申出了另一個課題,去TMF。或許真正需要的,只是3段簡單的if-else。

 

PD五顏六色的黑

我們也曾經遇到這樣的需求,為了方便銷售更好的篩選客戶,產品提出增加各式各樣標簽共計80餘個,並且支持標簽與標簽間,可以靈活的讓用戶選擇取交集還是取並集。最終我們發現,銷售名下客戶的中位數是8個,也就是說大部分銷售1~2頁可以翻完自己名下的所有客戶,當時我們也戲稱,標簽設計得比客戶還多。
部(hen)分(duo)產品經理沒有思考核心的問題到底是什麼,在淺層次瘋狂堆疊功能,美其名曰業務需要不斷試錯,實則缺少思考,缺少對問題根因的理解與判斷。在複雜這條路上越走越遠,也讓真正的簡單越來越難。

‘複雜’的光環與‘簡單’的暗淡

Simplicity has been difficult to implement in modern life, because it is against the spirit of a certain brand of people who seek sophistication so they can justify their profession.
-- Nassim Nicholas Taleb 《Antifragile:Things That Gain from Disorder》
譯:在現實生活中,簡單的做法一直難以實現,因為它有違某些努力尋求複雜化,以證明其工作合理性的人所秉持的精神。
為什麼大家更偏向複雜而遠離簡單,除了缺少思考,找不到問題的核心解以外,還有一個重要原因就是為了所謂的“證明自己”。Nassim Nicholas Taleb在 Antifragile:Things That Gain from Disorder 中提到一個觀點:在現實生活中,簡單的做法一直難以實現,因為它有違某些努力尋求複雜化,以證明其工作合理性的人所秉持的精神。
如同DDD在中小系統所帶來的災難一樣,根本原因更多是因為大家並不願意承認自己的系統是中小系統,自己所承接的業務是偏向簡單的業務。最終導致簡單的模塊賦以複雜的束縛,最終效率被工具本身所制約。
曾經我們有一個搜索器增量推送的訴求,當時用的blink來支持,blink支持海量數據處理,分散式集群能力等等。而我們本身並沒有海量數據,也沒有超高併發,最終上線後不僅用不上blink超強的能力,還因為blink的性能調優、自定義函數異常、類型轉換異常、資源申請及降級,以及為新人帶來的認知負荷等等,帶來了更大的不便。後面通過手寫JAVA,調用搜索器增量推送SDK的方式進行重構,簡單清晰,查問題成本也更低。當然,將blink畫到PPT里,那確實還挺高大上的。
‘複雜’總是伴隨著光環,當我們解決一個複雜問題後,我們會得到更多人的肯定,向大家證明和展示自己的實力。而簡單往往更‘暗淡’,如同上文提到的互換瓶蓋,大家並不會因此認可服務生的能力,甚至覺得也沒什麼大不了。如此往複,讓大家更青睞複雜,更遠離簡單。

『簡單』其實更複雜

Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple。
-- Steve Jobs
譯:簡單比複雜更難,你必須儘力理清思路才能做到簡單。
手機的HOME鍵是極簡主義的一個代表,據說小圓點的設計靈感是受到馬桶的啟發,用一個按鈕清除所有。
簡單並不代表容易,簡單意味著非聯接,而非聯接並不簡單。在降低複雜度上,軟體設計有一個核心理念叫“解耦”,核心思想是分離關註點,只有你聚焦的內容少了,你才不會覺得複雜。

KISS原則

Keep it Simple and Stupid
-- Robert S. Kaplan
譯:保持簡單和笨拙
KISS原則是Robert S. Kaplan提出的一個理論,Kaplan並非是一個軟體學家,他是平衡積分卡 Balanced Scorecard 創始人,而他所提出的這個理論對軟體行業依然適用。把事情變複雜很簡單,把事情變簡單很複雜。我們需要儘量讓複雜的問題簡明化、簡單化。
KISS原則的實現看似簡單,但實則並不容易。以最簡單的做法完成任務,但不斷引入複雜度並腐化系統的做法,被John Ousterhout教授稱之為「戰術龍卷風」。當你不斷打著KISS原則的旗號,以最簡單的做法堆疊功能時,最終會得到一個終極複雜體。軟體設計是一門藝術,前人的經驗可以給我們提供前進的方向,但我們也一定要時刻有自己的判斷。

 

UNIX的藝術

圖片

1974年UNIX系統在Communication of ACM上發表,正式向外界披露了UNIX系統。UNIX的成功也誕生了諸如Linux、BSD、Solaris、MacOSX等多個UNIX變種。UNIX奠基人之一的Doug Mcllroy曾經說,UNIX的設計理念就是一個程式只做一件事,並做好。 
All the philosophy really boils down to one iron law, the hallowed ‘KISS principle’ of master
engineers everywhere.
-- Eric Steven Raymond 《The Art of Unix Programming》
譯:所有的UNIX哲學濃縮為一條鐵律,那就是各地編程大師們奉為圭臬的KISS原則。 
UNIX的哲學根本,就是一部在持續踐行KISS原則的卓越工程。『維護如此重要而成本如此高昂,在寫程式時,要想到你不是寫給執行代碼的電腦看的,而是給人--將來閱讀維護源碼的人,包括你自己』-- The Art of Unix Programming

 

遺失的奧卡姆剃刀

Entities should not be multiplied beyond necessity.
-- William of Ockham 《Occam's Razor》
譯:如無必要,勿增實體。
奧卡姆剃刀也稱為奧康定律,最先並非在軟體界提出而是在哲學界。保持事情的簡單性,抓住根本,去掉無關內容,是奧卡姆剃刀的核心觀念。在軟體設計中,每一次的抽象,都是在放大本質因素,消除無關因素。奧卡姆剃刀的缺失,也讓我們的系統越來越複雜,我們總能發現有很多奇奇怪怪可有可無的代碼,散落在系統各處,增加這些代碼可能只需要幾分鐘,但移除這些代碼花費的精力與承擔的風險,卻數倍於此。

Maven的SNAPSHOT

Maven的SNAPSHOT設計是我覺得非常棒的一個設計,當版本號為1.0時,是正式版,當版本號是1.0-SNAPSHOT時,是快照版,直接通過名字進行區分,簡單清晰。
或許有人認為這比較粗暴,如果快照版後續還存在更多變種,那支撐起來會非常不優雅,應該用一個欄位或屬性來單獨表示正式版還是快照版,這樣更規範更易擴展。
過早的優化是萬惡的根源,或許他的擔憂是對的,但很慶幸當初Maven創始人沒這麼乾,將簡單延續了下來,事實也證明,它真的很美。

 

因為信任所以簡單

因為信任所以簡單,是阿裡的一個價值觀。有次周末打車去公司,師傅問你們不記錄相關線路和內容,如果有人打車跑別處去玩了怎麼辦,我回答因為信任所以簡單。我見過很多公司,為了約束員工,設定過非常繁雜的規則。而往往上有政策下有對策,公司與員工內耗在這無盡的拉扯中。
把握住問題的本質--信任。真實不裝,互相信任,沒那麼多顧慮猜忌,問題就簡單了,事情也就因此高效。

 

寫在最後

小時候打撞球,見到能翻袋,下底,長桿的人真厲害,幻想自己有一天能厲害到怎樣難的球都能打進。長大後發現,真正厲害的人,母球永遠不會輕易停在難打的地方。有能力解決複雜問題的人,我們給予掌聲,而能夠持續保持簡單保持純粹,應該得到更高的贊許。
參閱書籍:
1、《Antifragile:Things That Gain from Disorder》:https://book.douban.com/subject/34978407/
2、《The Art of Unix Programming》:https://book.douban.com/subject/1229959/
3、《The Mythical Man-Month》:https://book.douban.com/subject/6039354/
4、《Clean Architecture》:https://book.douban.com/subject/26915970/

 

作者|聶曉龍(率鴿)

本文來自博客園,作者:古道輕風,轉載請註明原文鏈接:https://www.cnblogs.com/88223100/p/We-are-not-good-at-dealing-with-simplicity.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作者:京東物流 王北永 姚再毅 李振 1 背景 目前,ducc實現了實時近乎所有配置動態生效的場景,但是配置是否實時生效,不能直觀展示每個機器上jvm內對象對應的參數是否已變更為準確的值,大部分時候需要查看日誌確認是否生效。 2 技術依賴 1)Jsf:京東RPC框架,用作機器之間的通訊工具 2)re ...
  • 2023-01-20 一、SpringMVC處理響應數據 1、處理響應數據方式一 (1)語法:使用ModelAndView對象作為返回值類型,處理響應數據 (2)底層實現原理 ①數據共用到request域 ②跳轉路徑方式:轉發 (3)示例代碼 @RequestMapping("/testModelA ...
  • 常見的網路IO模型有4種:同步阻塞IO、同步非阻塞IO、IO多路復用以及非同步非阻塞IO。 RPC會採用IO多路復用的機制來管理網路通信。 ...
  • 寫在前面 在開發的過程中,大多數人都需要對代碼進行測試。目前對於c/c++項目,可以採用google的gtest框架,除此之外在github上搜索之後可以發現很多其他類似功能的項目。但把別人的輪子直接拿來用,終究比不過自己造一個同樣功能的輪子更有成就感。作為“linux環境編程”系列文章的第一篇,本 ...
  • 基於 LGT8F328P LQFP32 的 Arduino Mini EVB, 這個板型資料較少, 記錄一下開發環境和燒錄過程以及當中遇到的問題. ...
  • 介紹一些我常用的ssh工具 1、Xshell ​ Xshell應該是一款家喻戶曉的ssh連接工具,本人有幸也在很長一段時間都在使用Xshell,但是Xshell他是收費的!而且每次關閉後都會有一個提示框,我很不喜歡,而且Xshell的ftp或其他插件都是需要額外自行下載的,對於文件傳輸不太方便,但是 ...
  • JavaScript 中的作用域指的是變數和函數的可訪問範圍。 JavaScript 中,閉包是一個函數對象,它可以訪問定義該函數的作用域里的變數,即使函數已經返回。閉包的特點是,它可以在其相關環境不存在時保留變數。閉包可以被保存到變數中併在以後使用。它具有兩個特征,一是可以訪問外部函數的變數,二是... ...
  • JavaScript 中的 this 關鍵字引用了所在函數正在被調用時的對象。在不同的上下文中,this 的指向會發生變化。可以通過 call, apply, bind 方法來改變 this 的上下文。 ...
一周排行
    -Advertisement-
    Play Games
  • 一:背景 1. 講故事 年前遇到了好幾例托管堆被損壞的案例,有些運氣好一些,從被破壞的托管堆記憶體現場能觀測出大概是什麼問題,但更多的情況下是無法做出準確判斷的,原因就在於生成的dump是第二現場,借用之前文章的一張圖,大家可以理解一下。 為了幫助更多受此問題困擾的朋友,這篇來整理一下如何 快狠準 的 ...
  • 前言 .NET6 開始,.NET Croe API 項目取消了 Startup.cs 文件,在 Program.cs 文件的 Main 函數中完成服務的註冊和中間件管道的管理。但當我們項目引入更多包的時候,Program.cs 文件也會看起來很臃腫。 而且,我們不只會有一個後端項目,為了方便快速創建 ...
  • 目錄 背景 get 與 post 的區別 所有介面都用 post 請求? 背景 最近在逛知乎的時候發現一個有趣的問題:公司規定所有介面都用 post 請求,這是為什麼? 看到這個問題的時候其實我也挺有感觸的,因為我也曾經這樣問過我自己。在上上一家公司的時候接到一個項目是從零開始搭建一個微服務,當時就 ...
  • *以下內容為本人的學習筆記,如需要轉載,請聲明原文鏈接 微信公眾號「englyf」https://mp.weixin.qq.com/s/2GFLTstDC7w6u3fTJxflNA 本文大概 1685 個字,閱讀需花 6 分鐘內容不多, 但也花了一些精力如要交流, 歡迎關註我然後評論區留言 謝謝你的 ...
  • 在新版本的pandas中,上述代碼會引起警告,建議改成SQLAlchemy connectable(engine/connection),後續代碼將引入這種升級的連接方式。 ...
  • 幾乎所有的高級編程語言都有自己的垃圾回收機制,開發者不需要關註記憶體的申請與釋放,Python 也不例外。Python 官方團隊的文章 https://devguide.python.org/internals/garbage-collector 詳細介紹了 Python 中的垃圾回收演算法,本文是這篇 ...
  • 如果您想查找高於或低於平均值的數字,可以不必計算該平均值,就能查看更高或更低的值。通過Java應用程式,可以自動突出顯示這些數字。除了快速突出顯示高於或低於平均值的值外,您還可以查看高於或低於的值的個數。現在讓我們看看如何在 Java應用程式中實現此操作。 引入jar包 導入方法1: 手動引入。將  ...
  • 第一種方式:使用{} firstDict = {"name": "wang yuan wai ", "age" : 25} 說明:{}為創建一個空的字典對象 第二種方式:使用fromkeys()方法 second_dict = dict.fromkeys(("name", "age")) #valu ...
  • 在golang中可以使用a := b這種方式將b賦值給a,只有當b能進行深拷貝時a與b才不會互相影響,否則就需要進行更為複雜的深拷貝。 下麵就是Go賦值操作的一個說明: Go語言中所有賦值操作都是值傳遞,如果結構中不含指針,則直接賦值就是深度拷貝;如果結構中含有指針(包括自定義指針,以及切片,map ...
  • 本文結合京東監控埋點場景,對解決樣板代碼的技術選型方案進行分析,給出最終解決方案後,結合理論和實踐進一步展開。通過關註文中的技術分析過程和技術場景,讀者可收穫一種樣板代碼思想過程和解決思路,並對Java編譯器底層有初步瞭解。 ...