軟件開發(fā)的簡單設(shè)計觀
作者 | 袁慎建
保持簡單
簡單是一個成年人司空見慣的詞,然而,大部分成年人卻覺得純真的孩子才是簡單的。
很多時候,人們習(xí)慣把“簡單”跟“容易”理解成一個意思。簡單和復(fù)雜多用于形容事物或人的屬性或狀態(tài),容易和困難一般形容達到某種目標的過程。生活中經(jīng)常聽到這樣的感慨:「人活簡單點真難??!」、「系統(tǒng)一不小心就搞復(fù)雜了」。這些感慨背后流露出一種心愿 -- 保持簡單。
對于人來說,保持簡單可能意味著人情世故的簡單、工作關(guān)系的簡單、心態(tài)的簡單。對于軟件系統(tǒng)來說,則意味著系統(tǒng)設(shè)計的簡單、部署運維的簡單等等。
三重境
看山是山,看水是水;看山不是山,看水不是水;看山是山,看水是水。
保持簡單的確不是一件容易的事情。禪宗提出的人生三境界中也詮釋了這個理:人從簡單開始,以復(fù)雜貫穿了大部分甚至整個人生,最后返璞歸真。
對應(yīng)到一個需求簡單的軟件系統(tǒng)中,系統(tǒng)的設(shè)計一開始處于簡單的狀態(tài)。然而軟件開發(fā)的核心問題是復(fù)雜多變的業(yè)務(wù)需求,隨著時間的推移,軟件系統(tǒng)可能呈現(xiàn)出以下三個狀態(tài):
正常情況下,沒有人希望系統(tǒng)處于第三個狀態(tài),而是希望從第二個狀態(tài)回到第一個狀態(tài)。映射到禪宗的人生三境界,系統(tǒng)的理想三境界是:
- 清晰 -- 單一化
- 復(fù)雜 -- 層級化
- 清晰 -- 模塊化
在面臨復(fù)雜多變的業(yè)務(wù)需求,如何設(shè)計一個恰好簡單夠用的系統(tǒng)?如何保持系統(tǒng)的高響應(yīng)力?程序員們一直都沒有停止對最佳實踐的探索,始終為這些目標奮斗。軟件開發(fā)的所有問題最終都能歸結(jié)到人身上,那么驅(qū)動程序員不斷改進的力量是什么?
我心中有一個答案:對簡單設(shè)計、高響應(yīng)力價值的認可,對簡單設(shè)計價值觀的深層內(nèi)化。
核心觀
價值觀往往給人一種感覺:看著這些高大上的詞匯,缺點什么,卻總又說不上來。比如極限編程(XP)的價值觀:溝通、簡單、反饋、勇氣、尊重。再比如 Scrum 的價值觀:專注、開放、承諾、勇氣、尊重。尤其是剛開始接觸這些知識體系的新人,每個詞都能看懂,只是不知道如何用它們?nèi)ブ笇?dǎo) XP 和 Scrum。
在 Thoughtworks 工作這么多年,我親自實踐過 XP 和 Scrum,也在很多場合傳授過它們,再回過頭來看,我深刻體會到一點——XP 和 Scrum 的那些實踐跟它們的價值觀都非常吻合。我能夠在日常開發(fā)以及培訓(xùn)和練習(xí)中去落地簡單設(shè)計,這背后驅(qū)使我不斷探索的是已內(nèi)化于心的觀念:
專注
在 Scrum 中,專注強調(diào)的是所有人都專注于 Sprint 目標,團隊同為一個目標努力。對于簡單設(shè)計,要專注在哪里呢?我結(jié)合自身經(jīng)歷的幾個典型的場景來看:
- 一上來匆匆忙忙編寫業(yè)務(wù)代碼,沒有Tasking,沒有測試,沒有設(shè)計,業(yè)務(wù)Scope逐步偏離或擴大
- 在編碼階段,聽到聲音:“你這個設(shè)計太土氣了,都沒用設(shè)計模式”,于是琢磨著怎么去套設(shè)計模式
- 在系統(tǒng)架構(gòu)設(shè)計階段,有人說:“什么年代了,你還不拆出幾個微服務(wù)”,于是嘗試拍腦袋拆出一個分布式單體
上述三個場景,究其根本,是沒能很好地專注于自己要實現(xiàn)的真實業(yè)務(wù)價值,要么缺乏思考和設(shè)計,要么受外界影響,舍本琢末。你可能會質(zhì)問:不應(yīng)該多做點設(shè)計來兼容后期可能出現(xiàn)的情況嗎?為未來做設(shè)計,難免會摻入不合時宜的猜測,不僅增加系統(tǒng)當前的復(fù)雜度,還可能浪費成本。
我覺得要始終保持對當下真實業(yè)務(wù)價值的專注,專注理解業(yè)務(wù)本質(zhì),專注于剛好夠用的設(shè)計,時刻讓系統(tǒng)保持簡單,盡可能跟業(yè)務(wù)模型保持匹配和同步。
克制
克制力是一項非常重要且需要長期培養(yǎng)的能力。由于受到太多外界的干擾而難以定靜,程序員經(jīng)常會因為沉浸在自己的世界里,可能出現(xiàn)樂觀估算,還可能經(jīng)常過度設(shè)計。
而實際上,大部分樂觀的估算會讓團隊交付面臨更多風(fēng)險,大部分健壯性設(shè)計會讓系統(tǒng)難以理解和修改。我想起來自己曾經(jīng)面試過的一個候選人,一個很簡單的業(yè)務(wù)需求,硬生生地套用了5種設(shè)計模式,嘆為觀止。
在日常交付項目和工作坊中,我會較為留意開發(fā)人員嘴里發(fā)出的 “我覺得”、“假如”、“萬一”、“以后”等用語,這些用語背后所隱藏的溢念(溢出的想法),很可能促使該開發(fā)人員交付一個不滿足需求的軟件,或者一個難以維護的系統(tǒng)。
我覺得程序員克制自己一個有效的方式是培養(yǎng)業(yè)務(wù)視角,站在用戶使用系統(tǒng)的視角嘗試深刻理解業(yè)務(wù),通過將業(yè)務(wù)需求進一步拆解成小顆粒度的任務(wù)來讓自己保持聚焦。Think Big(深刻理解業(yè)務(wù)問題并拆分),Start Small(每次只聚焦在某一個小的任務(wù)),Move Fast(快速完成一個個小的任務(wù)并獲得反饋)。
潔癖
我經(jīng)常在 Code Review 中被同事開玩笑說有代碼潔癖,比如對命名太較真了。一開始我會有所妥協(xié),畢竟軟件開發(fā)是一個團隊來完成的,如果因為某個人的潔癖而讓其他人不舒適,可能不利于團隊協(xié)作??墒菚r間后來告訴我,那些身披“不認真”或者“不嚴格”標簽的小魔頭會在后面出來制造各種噪音,比如命名看不懂、結(jié)構(gòu)不一致、架構(gòu)混亂臃腫等等。
做程序員這幾年,潔癖潛移默化影響著我的編碼和設(shè)計風(fēng)格,小到變量命名、代碼注釋、文檔管理,大到系統(tǒng)架構(gòu),我都會時刻保持警惕,盡其所能去消除噪音污染。在沒有其他不可抗拒的因素前提下,我都會盡力嘗試讓團隊接納自己對代碼潔癖的追求。
潔癖更側(cè)重于團隊個體成員,對于個體,可以通過不斷提升自己的整潔代碼認知來強化它,并嘗試在實踐中去運用它們。而對于團隊,我想到一條指導(dǎo)原則:任何有助于提升系統(tǒng)質(zhì)量的潔癖都不應(yīng)該被忽視,團隊應(yīng)該盡力接納并落實。
懶惰
恰當?shù)摹皯卸琛笔且粋€優(yōu)秀的程序員必備的特質(zhì),因為 Ta 總是勤于思考如何才能少做重復(fù)的事情。
懶惰聽起來是一個負面的詞,中國幾千年的文化價值觀在告訴每一個人要做勤奮努力的人。在軟件開發(fā)領(lǐng)域,我認為恰當?shù)膽卸枋墙夥懦绦騿T生產(chǎn)力、保持系統(tǒng)簡單的助推劑,比如:
- 需求或設(shè)計變更,懶得改太多代碼。怎么辦?消除代碼重復(fù),隔離和封裝變化,分離關(guān)注點
- 手工集成和測試,懶得重復(fù)做。怎么辦?增加自動化測試并做好CI/CD
- 用戶鑒權(quán)分散在各個服務(wù)中,懶得修改所有的服務(wù)。怎么辦?引入API Gateway
- 新人上項目,搭建環(huán)境反復(fù)找我,懶得重復(fù)講。怎么辦?編寫自動化腳本和文檔指南
如果每次面對相同的問題,不得不花精力去處理,在這種毫無挑戰(zhàn)的重復(fù)性工作中,人通常很容易犯錯,所以,當手懶得去做這些事情,懶惰會驅(qū)使大腦去思考一種更加高效的方式,比如隔離變化將其封裝,引入自動化,從而取代一遍遍重復(fù)的操作,并且大腦還會思考如何運用 KISS(Keep it Simple and Stupid),Yagni,如無必要,勿增實體。
有一種看似很”勤快”的CCCV(CMD + C | CMD + V)編碼行為,這些行為背后跟我提倡的懶惰大相徑庭。CCCV行為是思想上的懶惰,在這種思維的指導(dǎo)下,雙手會樂此不疲去重復(fù)做很多重復(fù)的事情,CCCV當規(guī)避之。
勤于思考,惰于盲行,做一個具備恰當惰性的程序員是一種快樂。
需要勇氣
在 XP 和 Scrum 鼓勵人們要有勇氣去做正確的事情、處理棘手的問題、做出承諾、堅持原則、拒絕損害工作的行為、暴露自己的不足并尋求幫助、提供有建設(shè)性的意見等。
要保持簡單,這些勇氣也是不可或缺的。同時,我提倡程序員培養(yǎng) 保持專注、克制溢念、養(yǎng)成代碼潔癖、滋養(yǎng)恰當?shù)膽卸璧挠職狻?/p>