掃二維碼與項(xiàng)目經(jīng)理溝通
我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
作者 | 袁慎建

10年積累的成都做網(wǎng)站、網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有泰興免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
歡歡:“你看我的代碼用了策略模式和狀態(tài)模式,假如后面客戶會(huì)有這樣的需求,可以無縫擴(kuò)展,多么健壯!” 清揚(yáng)一臉狐疑,心中念叨了數(shù)遍 :“哼,過度設(shè)計(jì)!”,只見她欲言又止,好幾次話到嘴邊又被自己咽回去了。
這種關(guān)于設(shè)計(jì)的討論,袁帥最近一周不是第一次聽到了,就在昨天他還看到清揚(yáng)和正義的一次口水仗。最近清揚(yáng)有點(diǎn)仕途不順,幾次被結(jié)對的搭檔懟得無言以對。袁帥想為他的Buddy清揚(yáng)“討回公道”,但不是直接出面幫清揚(yáng)懟回去。
周五下午,公司內(nèi)部的敏捷工程實(shí)踐指導(dǎo)手冊上醒目的三條價(jià)值觀的「簡單性」讓袁帥陷入了沉思:
簡單性:我們重視剛剛夠用的設(shè)計(jì)。只為當(dāng)下設(shè)計(jì),不為未來可能出現(xiàn)的需求做設(shè)計(jì)。但是,我們做出的決策應(yīng)當(dāng)允許軟件快速變更,能夠快速響應(yīng)需求變化。
「簡單性」,看起來也似乎明白在講什么,可什么是剛剛夠用的設(shè)計(jì)呢?這句話讓他想起來當(dāng)年他在一次面向?qū)ο笥?xùn)練營的課后跟某個(gè)學(xué)員說過的一句話:“設(shè)計(jì)猶如西紅柿炒雞蛋,鹽要恰到好處?!?這句話是如此的正確卻又無比空洞。
設(shè)計(jì)的好壞本身沒有一個(gè)標(biāo)準(zhǔn)的答案,這么多年,袁帥也在跟著軟件界各路神仙學(xué)習(xí)設(shè)計(jì)原則,仍然處在似懂非懂的狀態(tài)。他也深知每個(gè)人心中都有一桿秤。什么是好的設(shè)計(jì)?便成了公說公有理,婆說婆有理的問題,誰也難以說服誰。
這一次他不太想提那些空空如也的東西,為了能夠讓清揚(yáng)快速掌握要點(diǎn),他嘗試將范圍縮小到敏捷團(tuán)隊(duì)程序員交付用戶故事卡時(shí)的編碼設(shè)計(jì),避開架構(gòu)設(shè)計(jì)。從變量、常量、方法、類、類與類之間的關(guān)系、對象的交互開始。
周六,袁帥很早就鉆到書房,點(diǎn)燃背景音樂《稻香》,打開博客主頁,發(fā)現(xiàn)了一篇多年前寫的文章《簡單設(shè)計(jì)》,仔細(xì)通讀一遍之后,他覺得還不錯(cuò),可以作為入門,發(fā)給清揚(yáng)閱讀,約下周一大一早去公司討論。
他花了近一個(gè)小時(shí)將文字潤色,也基于最近對設(shè)計(jì)的體會(huì)調(diào)整了部分內(nèi)容,保留了文章的整體脈絡(luò)。
抽象的設(shè)計(jì)問題大大提升了初學(xué)者的學(xué)習(xí)門檻,想得太多怕被說過度設(shè)計(jì),吃飽撐著沒事找事。想少了,又怕被人認(rèn)為能力不足,無腦編碼。到底怎么辦,怎么樣才能做出好的設(shè)計(jì)?SOLID、GoF的23種設(shè)計(jì)模式、STUPID、GRASP這些原則學(xué)會(huì)了就可以了嗎?No,統(tǒng)統(tǒng)忘掉這些抽象不接地氣的設(shè)計(jì)原則。
起步,盡量別為難自己。極限編程領(lǐng)域的大師程序員Kent Beck很早前就提出了4條相對容易理解的參考原則:
「通過測試」 通常會(huì)被一概地理解為通過自己在項(xiàng)目中的各種測試(自動(dòng)化 + 手工),這么理解,也沒有什么問題,但是需要滿足兩個(gè)前提條件:
如果你的項(xiàng)目中沒法滿足這兩點(diǎn),當(dāng)然,99%的項(xiàng)目是做不到的(還有1%存在傳說中)。此時(shí)你需要換一個(gè)角度去理解 通過測試。
你為什么寫測試?測試在測什么?不就是為了增強(qiáng)你對系統(tǒng)功能是否滿足了業(yè)務(wù)需求的信心嗎?所以「通過測試 」廣義理解為要滿足業(yè)務(wù)需求,不論是自動(dòng)化測試還是手工測試,你需要做的是滿足業(yè)務(wù)需求,只不過我們提倡盡可能編寫足夠的自動(dòng)化回歸測試。
重復(fù)乃萬惡之源——Kent Beck 沒有說過
重復(fù)意味著低內(nèi)聚、高耦合,導(dǎo)致的后果是難以修改(霰彈式修改),必然降低系統(tǒng)對變化的響應(yīng)力。響應(yīng)力的降低勢必會(huì)造成維護(hù)工作量的提升,我的簡單設(shè)計(jì)價(jià)值觀 一文中的 懶惰 將驅(qū)使我盡我所能消除這些重復(fù),從而減少修改時(shí)的工作量,提升軟件的響應(yīng)力。
揭示意圖,聽起來是一個(gè)不可言說的概念,怎樣表示揭示意圖了呢?對于這一條,我們很難有一個(gè)標(biāo)準(zhǔn)且完美的答案,做不到完美,但不妨礙我們努力嘗試趨近完美。
你可以在編碼過程中,不斷問自己:代碼容易理解嗎?它有沒有偏離它的初衷(業(yè)務(wù)需求)?緊接著,進(jìn)一步探索這背后暴露的行為信號 -- 「解釋」:
這幾個(gè)問題會(huì)讓你不斷反思你的代碼能夠體現(xiàn)業(yè)務(wù)初衷嗎?變量、方法以及類的命名等,你時(shí)刻都保持警惕的是:賦予它一個(gè)更加準(zhǔn)確表達(dá)業(yè)務(wù)的名字,一個(gè)不要額外解釋的名字。從而讓讀者能夠在深入細(xì)節(jié)之前就能夠在較高層次上快速理解代碼的意圖。
既然說的是代碼,那么充斥在你的代碼庫中的任何東西都可以理解是元素。當(dāng)然,我們還是焦點(diǎn)聚焦在與代碼相關(guān)的元素,比如,變量、常量、注釋、注解、關(guān)鍵字、包。
「最少元素」 的核心思想是:在不必要的時(shí)候,盡可能減少代碼元素來降低代碼復(fù)雜度,保持簡潔,貫徹less is more的思想,它道出了簡單設(shè)計(jì)的精髓。
簡單設(shè)計(jì)前四條原則給設(shè)計(jì)決策提供了指導(dǎo),在實(shí)際運(yùn)用過程中,當(dāng)面臨沖突時(shí),我們?nèi)绾稳∩?,Kent Beck也提出一個(gè)優(yōu)先級:通過測試 > 消除重復(fù) >= 揭示意圖 > 最少元素。
以上四條優(yōu)先級依次降低,這就話有點(diǎn)類似敏捷宣言中的最后一句:也就是說,盡管右項(xiàng)有其價(jià)值,我們更重視左項(xiàng)的價(jià)值。
周末過的飛快,清揚(yáng)讀完了袁帥發(fā)給他的《簡單設(shè)計(jì)》,而且讀了很多遍,一腦子的疑問等著要找袁帥探討。她比往日提前了一個(gè)小時(shí)到了辦公室,只見袁帥已經(jīng)在工位,一副就等她來戰(zhàn)的態(tài)勢。
還沒等清揚(yáng)開口,袁帥遞給她四張紅色卡片,是他的手寫筆記,清揚(yáng)見字跡工整,貌似她從未見過袁帥如此認(rèn)真寫過字,頗感意外和感動(dòng),格外認(rèn)真地閱讀起來。
“清揚(yáng),考你一個(gè)腦筋急轉(zhuǎn)彎 -- 在工作中你的領(lǐng)導(dǎo)的領(lǐng)導(dǎo)的領(lǐng)導(dǎo)的領(lǐng)導(dǎo)(4個(gè)人),當(dāng)他們給你的指令有沖突時(shí),你該聽誰的?”?!爱?dāng)然是聽更高級領(lǐng)導(dǎo)的指令啊!”清揚(yáng)條件反射式快速回答到。
袁帥見狀會(huì)心一笑,清揚(yáng)也撓撓頭貌似明白袁帥的意思?!翱墒牵疫€是......” 還沒等清揚(yáng)說完,袁帥示意她靠近來看他早早準(zhǔn)備好的代碼。
示例一:
袁帥快速出招:“這段代碼在做什么?用簡單設(shè)計(jì)框架怎么解讀?”。清揚(yáng)敏捷地接招:“抽取公共方法,為了「消除重復(fù)」而違背「最少元素」?!?/p>
示例二:
“常量代替魔鬼數(shù)字,為了「揭示意圖」而違背「最少元素」?!边€沒等袁帥發(fā)問,清揚(yáng)搶先回答,當(dāng)然也贏了袁帥的大拇指(向上的)。
一晃就08:55了,袁帥見Jeany朝他走來,搭載著一副即將要開會(huì)的眼神,便起身準(zhǔn)備去會(huì)議室跟她商量晚上OOBootcamp最后一次課的安排。
“喂,我還有一個(gè)疑問...” “桌上還有一張藍(lán)色卡片,你看能不能解答你的疑問?!?袁帥扭著頭得意地給清揚(yáng)一個(gè)微笑,就跟Jeany進(jìn)入了會(huì)議室。
清揚(yáng)拿起卡片開始閱讀:
清揚(yáng)很是驚訝袁帥竟然如此懂她,不愧是優(yōu)秀的Buddy,一大早開啟了美好的工作節(jié)奏。她讀完卡片,繼續(xù)閱讀袁帥留給她的幾個(gè)代碼示例,15分鐘過去了,她對簡單設(shè)計(jì)算是有點(diǎn)體會(huì)了,拿起一張綠色的卡片認(rèn)真寫下了:
跟Jeany開完會(huì),袁帥回到工位上,看到清揚(yáng)留下的卡片,深感欣慰,他清楚清揚(yáng)已經(jīng)入門了,日后Code Review不再會(huì)被懟得無言以對,而他幫清揚(yáng)“討回公道”的小心愿很快就要實(shí)現(xiàn)。
此時(shí),他坐下來喝了口水,發(fā)出了感慨 -- Kent Beck 提出的簡單設(shè)計(jì)原則更多關(guān)注的是代碼設(shè)計(jì),簡單設(shè)計(jì)思想其實(shí)也能運(yùn)用在架構(gòu)設(shè)計(jì)、溝通協(xié)作上。
架構(gòu)設(shè)計(jì):
溝通協(xié)作:
簡單設(shè)計(jì)五原則中,測試要確保通過(滿足需求)、重復(fù)應(yīng)該被消除、元素沒必要就不要存在,這幾條看起來相對具體,而且能見字如意。但揭示意圖這樣一個(gè)每個(gè)人持有不一樣標(biāo)準(zhǔn)的概念,它代表了代碼的可理解性,可理解性的參考則要回到業(yè)務(wù)源頭,是否準(zhǔn)確表達(dá)了業(yè)務(wù)概念。最后,優(yōu)先級原則是萬萬不可忽略的,否則這個(gè)框架就失去了靈魂和生命力。
袁帥做了多年的軟件開發(fā)和培訓(xùn),他心里很清楚,那個(gè)完美的答案可能不存在。軟件開發(fā)是一種知識工作,設(shè)計(jì)又是仁者見仁智者見智,簡單設(shè)計(jì)五原則能在一定程度上幫助程序員少走彎路。
除了這些,在團(tuán)隊(duì)社交活動(dòng)發(fā)生探討是一個(gè)非常有效的途徑。這也是他如此重視在工作坊中引入社交活動(dòng)的原因。代碼是否易讀懂,除了自我審視,還需要多幾個(gè)大腦,比如:Code Review、結(jié)對編程。

我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流