歡歡:“你看我的代碼用了策略模式和狀態(tài)模式汪厨,假如后面客戶會有這樣的需求赃春,可以無縫擴展,多么健壯劫乱!” 清揚一臉狐疑织中,心中念叨了數(shù)遍 :“哼,過度設計衷戈!”狭吼,只見她欲言又止,好幾次話到嘴邊又被自己咽回去了殖妇。
這種關于設計的討論刁笙,袁帥最近一周不是第一次聽到了,就在昨天他還看到清揚和正義的一次口水仗谦趣。最近清揚有點仕途不順疲吸,幾次被結對的搭檔懟得無言以對。袁帥想為他的Buddy清揚“討回公道”前鹅,但不是直接出面幫清揚懟回去摘悴。
設計的標準在哪里?
周五下午嫡纠,公司內部的敏捷工程實踐指導手冊上醒目的三條價值觀的「簡單性」讓袁帥陷入了沉思:
簡單性:我們重視剛剛夠用的設計烦租。只為當下設計延赌,不為未來可能出現(xiàn)的需求做設計除盏。但是,我們做出的決策應當允許軟件快速變更挫以,能夠快速響應需求變化者蠕。
「簡單性」,看起來也似乎明白在講什么掐松,可什么是剛剛夠用的設計呢踱侣?這句話讓他想起來當年他在一次面向對象訓練營的課后跟某個學員說過的一句話:“設計猶如西紅柿炒雞蛋,鹽要恰到好處大磺÷站洌” 這句話是如此的正確卻又無比空洞。
設計的好壞本身沒有一個標準的答案杠愧,這么多年待榔,袁帥也在跟著軟件界各路神仙學習設計原則,仍然處在似懂非懂的狀態(tài)。他也深知每個人心中都有一桿秤锐锣。什么是好的設計腌闯?便成了公說公有理,婆說婆有理的問題雕憔,誰也難以說服誰姿骏。
這一次他不太想提那些空空如也的東西,為了能夠讓清揚快速掌握要點斤彼,他嘗試將范圍縮小到敏捷團隊程序員交付用戶故事卡時的編碼設計分瘦,避開架構設計。從變量琉苇、常量擅腰、方法、類翁潘、類與類之間的關系趁冈、對象的交互開始。
重溫舊文:簡單設計
周六拜马,袁帥很早就鉆到書房渗勘,點燃背景音樂《稻香》,打開博客主頁俩莽,發(fā)現(xiàn)了一篇多年前寫的文章《簡單設計》旺坠,仔細通讀一遍之后,他覺得還不錯扮超,可以作為入門取刃,發(fā)給清揚閱讀,約下周一大一早去公司討論出刷。
他花了近一個小時將文字潤色璧疗,也基于最近對設計的體會調整了部分內容,保留了文章的整體脈絡馁龟。
用具體的詞匯表達設計
抽象的設計問題大大提升了初學者的學習門檻崩侠,想得太多怕被說過度設計,吃飽撐著沒事找事坷檩。想少了却音,又怕被人認為能力不足,無腦編碼矢炼。到底怎么辦系瓢,怎么樣才能做出好的設計?SOLID句灌、GoF的23種設計模式夷陋、STUPID、GRASP這些原則學會了就可以了嗎?No肌稻,統(tǒng)統(tǒng)忘掉這些抽象不接地氣的設計原則清蚀。
起步,盡量別為難自己爹谭。極限編程領域的大師程序員Kent Beck很早前就提出了4條相對容易理解的參考原則:
原則一:通過測試(信仰)
「通過測試」 通常會被一概地理解為通過自己在項目中的各種測試(自動化 + 手工)枷邪,這么理解,也沒有什么問題诺凡,但是需要滿足兩個前提條件:
- 測試覆蓋率達到100%
- 所有測試都是有效的
如果你的項目中沒法滿足這兩點东揣,當然,99%的項目是做不到的(還有1%存在傳說中)腹泌。此時你需要換一個角度去理解 通過測試嘶卧。
你為什么寫測試?測試在測什么凉袱?不就是為了增強你對系統(tǒng)功能是否滿足了業(yè)務需求的信心嗎芥吟?所以「**通過測試 **」廣義理解為要滿足業(yè)務需求,不論是自動化測試還是手工測試专甩,你需要做的是滿足業(yè)務需求钟鸵,只不過我們提倡盡可能編寫足夠的自動化回歸測試。
原則二:消除重復(職責)
重復乃萬惡之源——Kent Beck 沒有說過
重復意味著低內聚涤躲、高耦合棺耍,導致的后果是難以修改(霰彈式修改),必然降低系統(tǒng)對變化的響應力种樱。響應力的降低勢必會造成維護工作量的提升蒙袍,我的簡單設計價值觀 一文中的* 懶惰* 將驅使我盡我所能消除這些重復,從而減少修改時的工作量嫩挤,提升軟件的響應力害幅。
原則三:揭示意圖(初衷)
揭示意圖,聽起來是一個不可言說的概念俐镐,怎樣表示揭示意圖了呢矫限?對于這一條,我們很難有一個標準且完美的答案佩抹,做不到完美,但不妨礙我們努力嘗試趨近完美取董。
你可以在編碼過程中棍苹,不斷問自己:代碼容易理解嗎?它有沒有偏離它的初衷(業(yè)務需求)茵汰?緊接著枢里,進一步探索這背后暴露的行為信號 -- 「解釋」:
- 新人了解了業(yè)務需求后,能夠第一時間清晰地從代碼中找到對應的代碼嗎?
- 你需要額外對一個新人解釋代碼的含義嗎栏豺?如果要彬碱,你要解釋到什么程度?
這幾個問題會讓你不斷反思你的代碼能夠體現(xiàn)業(yè)務初衷嗎奥洼?變量巷疼、方法以及類的命名等,你時刻都保持警惕的是:賦予它一個更加準確表達業(yè)務的名字灵奖,一個不要額外解釋的名字嚼沿。從而讓讀者能夠在深入細節(jié)之前就能夠在較高層次上快速理解代碼的意圖。
原則四:最少元素(精髓)
既然說的是代碼瓷患,那么充斥在你的代碼庫中的任何東西都可以理解是元素骡尽。當然,我們還是焦點聚焦在與代碼相關的元素擅编,比如攀细,變量、常量爱态、注釋辨图、注解、關鍵字肢藐、包故河。
「最少元素」 的核心思想是:在不必要的時候,盡可能減少代碼元素來降低代碼復雜度吆豹,保持簡潔鱼的,貫徹less is more的思想,它道出了簡單設計的精髓痘煤。
原則五:前四條優(yōu)先級依次降低(靈魂)
簡單設計前四條原則給設計決策提供了指導凑阶,在實際運用過程中,當面臨沖突時衷快,我們如何取舍宙橱,Kent Beck也提出一個優(yōu)先級:通過測試 > 消除重復 >= 揭示意圖 > 最少元素。
以上四條優(yōu)先級依次降低蘸拔,這就話有點類似敏捷宣言中的最后一句:也就是說师郑,盡管右項有其價值,我們更重視左項的價值调窍。
- 通過測試
- 消除重復
- 揭示意圖
- 最少元素
- 以上四條優(yōu)先級依次降低
優(yōu)先級幫助揭開迷霧
周末過的飛快宝冕,清揚讀完了袁帥發(fā)給他的《簡單設計》,而且讀了很多遍邓萨,一腦子的疑問等著要找袁帥探討地梨。她比往日提前了一個小時到了辦公室菊卷,只見袁帥已經(jīng)在工位,一副就等她來戰(zhàn)的態(tài)勢宝剖。
還沒等清揚開口洁闰,袁帥遞給她四張紅色卡片,是他的手寫筆記万细,清揚見字跡工整扑眉,貌似她從未見過袁帥如此認真寫過字,頗感意外和感動雅镊,格外認真地閱讀起來襟雷。
“清揚,考你一個腦筋急轉彎 -- 在工作中你的領導的領導的領導的領導(4個人)仁烹,當他們給你的指令有沖突時耸弄,你該聽誰的?”卓缰〖瞥剩“當然是聽更高級領導的指令啊征唬!”清揚條件反射式快速回答到捌显。
袁帥見狀會心一笑,清揚也撓撓頭貌似明白袁帥的意思总寒》鐾幔“可是,我還是......” 還沒等清揚說完摄闸,袁帥示意她靠近來看他早早準備好的代碼善镰。
Talk is cheap
示例一:
袁帥快速出招:“這段代碼在做什么?用簡單設計框架怎么解讀年枕?”炫欺。清揚敏捷地接招:“抽取公共方法,為了「消除重復」而違背「最少元素」熏兄∑仿澹”
示例二:
“常量代替魔鬼數(shù)字,為了「揭示意圖」而違背「最少元素」摩桶∏抛矗”還沒等袁帥發(fā)問,清揚搶先回答典格,當然也贏了袁帥的大拇指(向上的)岛宦。
一晃就08:55了,袁帥見Jeany朝他走來耍缴,搭載著一副即將要開會的眼神砾肺,便起身準備去會議室跟她商量晚上OOBootcamp最后一次課的安排。
“喂防嗡,我還有一個疑問...” “桌上還有一張藍色卡片变汪,你看能不能解答你的疑問∫铣茫” 袁帥扭著頭得意地給清揚一個微笑裙盾,就跟Jeany進入了會議室。
清揚拿起卡片開始閱讀:
清揚很是驚訝袁帥竟然如此懂她他嫡,不愧是優(yōu)秀的Buddy番官,一大早開啟了美好的工作節(jié)奏。她讀完卡片钢属,繼續(xù)閱讀袁帥留給她的幾個代碼示例徘熔,15分鐘過去了,她對簡單設計算是有點體會了淆党,拿起一張綠色的卡片認真寫下了:
- 通過測試(信仰酷师,不可動搖)
- 消除重復(職責,盡職盡責)
- 揭示意圖(初衷染乌,不忘初心)
- 最少元素(精髓山孔,精煉簡潔)
- 以上四條優(yōu)先級依次降低(靈魂,賦予生命)
簡單設計遐想
跟Jeany開完會荷憋,袁帥回到工位上台颠,看到清揚留下的卡片,深感欣慰勒庄,他清楚清揚已經(jīng)入門了串前,日后Code Review不再會被懟得無言以對,而他幫清揚“討回公道”的小心愿很快就要實現(xiàn)锅铅。
此時酪呻,他坐下來喝了口水,發(fā)出了感慨 -- Kent Beck 提出的簡單設計原則更多關注的是代碼設計盐须,簡單設計思想其實也能運用在架構設計玩荠、溝通協(xié)作上。
架構設計
- 我們應該最先考慮的是滿足業(yè)務的系統(tǒng)架構(通過測試:性能贼邓、穩(wěn)定性等)阶冈。
- 借助DDD來合理的劃分微服務(揭示意圖:明確限界上下文)。
- 提取公共服務組件來分離關注點(消除重復:API Gateway塑径、BFF等)女坑。
- 最后,我們在滿足了前三點的前提下盡可能簡化系統(tǒng)架構中的組件(最少元素)统舀。
溝通協(xié)作
- 在與客戶正式場合的溝通中匆骗,我們始終應該明確溝通主題劳景,確定目標(通過測試 )。
- 通過加強結構思考力來提升表達的結構性和清晰度碉就,從而達到言簡意賅(消除重復盟广,揭示意圖 )。
- 最后瓮钥,我們達到了前面三點之后盡量不說多余的廢話(最少元素)筋量。
簡單不僅如此
簡單設計五原則中,測試要確保通過(滿足需求)碉熄、重復應該被消除桨武、元素沒必要就不要存在,這幾條看起來相對具體锈津,而且能見字如意呀酸。但揭示意圖這樣一個每個人持有不一樣標準的概念,它代表了代碼的可理解性一姿,可理解性的參考則要回到業(yè)務源頭七咧,是否準確表達了業(yè)務概念。最后叮叹,優(yōu)先級原則是萬萬不可忽略的艾栋,否則這個框架就失去了靈魂和生命力。
袁帥做了多年的軟件開發(fā)和培訓蛉顽,他心里很清楚蝗砾,那個完美的答案可能不存在。軟件開發(fā)是一種知識工作携冤,設計又是仁者見仁智者見智悼粮,簡單設計五原則能在一定程度上幫助程序員少走彎路。
除了這些曾棕,在團隊社交活動發(fā)生探討是一個非常有效的途徑扣猫。這也是他如此重視在工作坊中引入社交活動的原因。代碼是否易讀懂翘地,除了自我審視申尤,還需要多幾個大腦,比如:Code Review衙耕、結對編程昧穿。
推薦閱讀
文/Thoughtworks 袁慎建
原文鏈接:https://insights.thoughtworks.cn/code-simple-design-five-principles/