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

来源: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
  • 就像 Web Api 介面可以對入參進行驗證,避免用戶傳入非法的或者不符合我們預期的參數一樣,選項也可以對配置源的內容進行驗證,避免配置中的值與選項類中的屬性不對應或者不滿足預期,畢竟大部分配置都是通過字元串的方式,驗證是很有必要的。 1. 註解驗證 像入參驗證一樣,選項驗證也可以通過特性註解方便地 ...
  • 原文作者:aircraft 原文鏈接:https://www.cnblogs.com/DOMLX/p/17270107.html 加工的泛型類如下: using System; using System.Collections.Generic; using System.IO; using Syst ...
  • 在前一篇文章,我們瞭解瞭如何通過.NET6+Quartz開發基於控制台應用程式的定時任務,今天繼續在之前的基礎上,進一步講解基於ASP.NET Core MVC+Quartz實現定時任務的可視化管理頁面,僅供學習分享使用,如有不足之處,還請指正。 涉及知識點 Quartz組件,關於Quartz組件的 ...
  • 面向對象1 面向對象,更在乎的結果,而過程的實現並不重要 IDea快捷鍵(基礎版) | 快捷鍵 | 作用 | | | | | ctrl + / | 快捷註釋 | | ctrl + shift + / | 多行註釋 | | ctrl + d | 快速複製 | | ctrl + shift + up/d ...
  • NX中的checkmate功能是用於檢查模型、圖紙數據的工具,在UGOPEN中有例子。手動操作可以檢查已載入的裝配下所有零部件,可以設置通過後保存模型,檢查結果保存到Teamcenter中,預設保存在零組件版本下。 代碼中可以設置多個檢查規則。相關設置可以在用戶預設設置中進行設置。 1 // 2 / ...
  • JavaSE 運算符 算術運算符:+,-,*,/,%,++(自增),--(自減) i++:先用後+1;++i:先+1後用 賦值運算符:= 擴展賦值運算符:+=,-=,*=,/= a+=b >a=a+b: ​ 可讀性差,但是編譯效率高,且會自動進行類型轉換; ​ 當ab為基本數據類型時,a+b和b+a ...
  • 面向對象2 訪問修飾符 | | private | default | protected | public | | | | | | | | 當前類 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_che ...
  • 推薦一些學習qml教程 Qt官方的QML教程: https://doc.qt.io/qt-5/qtqml-index.html 這是一個由Qt官方提供的完整的QML教程,包含了所有基本知識和高級語法。 QML中文網:http://www.qmlcn.com/ 這是一個非常不錯的中文QML學習網站,提 ...
  • QAbstractBUtton: 所有按鈕控制項的基類 提供按鈕的通用功能 繼承自QWidget 屬於抽象類別,不能直接去使用,必須藉助於子類(除非你覺得子類不夠用,想自定義一個按鈕) 大部分功能之前已經使用過,在這裡只作簡單介紹 文本設置: setText(str) :設置按鈕提示文本 text() ...
  • 使用 VLD 記憶體泄漏檢測工具輔助開發時整理的學習筆記。本篇介紹 VLD 配置文件中配置項 StartDisabled 的使用方法。 ...