前言
寫作背景
我想先從自己第一次接觸設計模式說起,這段回憶並不美好。
在畢業後的第二年,我在一次面試中被問到設計模式。當時的我甚至沒有聽說過設計模式,鎩羽而歸後,我便下定決心要攻克它。首先,我閱讀的是《設計模式:可重複使用物件導向軟體的基礎》,但很快便敗下陣來。這本被奉為「設計模式聖經」的著作,由於偏學術的行文風格,以及理論化的講解,使像我這樣的初學者難以理解。此外,書中的例子用C++ 和Smalltalk 語言撰寫,對像我這樣的Java 程式設計師來說更是雪上加霜。當然,《設計模式:可重複使用物件導向軟體的基礎》一書是無可撼動的經典。時至今日,每次翻閱它時,我都會有新的感悟。只是對當時的我來說,它的學習門檻有些高。
之後,我又找了幾本適合初學者的設計模式圖書,在系統學完後,可以說,設計模式顛覆了我對軟體開發的認知。那些枯燥的程式,變得鮮活起來;那些抽象的程式,變得具象起來。曾經被「奴役」於程式之中的我,現在卻像一位「造物主」,在軟體世界中「呼風喚雨」。
在體會到設計模式的美妙之後,我開始向身邊的朋友推薦,朋友也驚歎道:「程式竟然還能這麼寫!」在工作中,我開始「刻意」使用設計模式,現在回想起來,屬實有過度設計之嫌,但大量的設計經驗也是在此過程中累積下來的。
在近幾年的工作中,我更加追求程式的重複使用性、複雜度及開發成本的平衡。合理的選擇同樣少不了設計模式的知識做支撐。
誠然,市面上已經存在很多優秀的設計模式圖書,但以漫畫形式撰寫的設計模式圖書還很少。我兒時喜愛畫畫,也曾在少年宮學習,但由於和奧數課衝突,只能遺憾作罷。可是誰又能想到,在命運的齒輪轉動30 年後,我能將愛好與專業相結合,寫了一本書。
我第一次嘗試漫畫形式的技術寫作是在2018 年。此後,我寫作的一篇名為《圖文徹底搞懂非對稱加密》的漫畫技術文章,累計閱讀量超10 萬次,並收穫了很多正面的評價。我發現,在講解枯燥技術的文章中適當穿插幽默、風趣的漫畫,不但有助讀者理解,而且能調動讀者的閱讀興趣。從此,我更加堅定地以漫畫形式創作技術文章。
在本書中,我用「在情景對話中穿插漫畫」的形式講解設計模式,希望本書能帶給讀者一種全新的學習體驗。如果讀者在深入技術學習時還能開心一笑,我會倍感欣慰。
學習建議
在閱讀本書前,首先,需要具備Java 語言或其他物件導向語言的程式設計基礎。為了降低閱讀門檻,書中程式盡可能使用最基本的語法,對程式設計水準的要求並不高。其次,需要了解物件導向的特性——封裝、繼承、多態。書中有大量的程式結構圖,只要具備基礎的UML 知識,便可以讀懂。
我建議,設計模式的初學者先閱讀本書的前兩章,在對設計模式有了一定程度的認知,並了解設計原則後,再開始學習各種設計模式。若在學習之初難以完全理解設計原則也不必擔心,在後面的章節中,我會結合設計模式多次講到常見的設計原則。書中對每種設計模式的講解獨立成章,讀者既可以按順序閱讀,也可以按照自己的需要選擇閱讀。
本書從生活中常見的例子切入,展開對每種設計模式的講解。讀者可以跟隨這些例子拓展思維,思考這樣設計帶來了什麼收益、涉及哪些主體、主體間如何配合、各自的職責是什麼。設計模式是一種思想,學習設計模式重在悟透設計思想,而非急於用程式實現。
書中有大量的範例程式,建議讀者在閱讀的同時動手實踐,以便加深記憶和理解。在工作中,如果想使用某種設計模式,可以參考這些程式,但真實的場景遠比書中的例子複雜得多。讀者可以先從形式上開始模仿,當能夠靈活運用設計思想解決問題時,形式反而沒那麼重要了。大膽應用,是真正掌握設計模式的必經之路。
本書特色
本書採用老師與學生對話的形式進行講解,為此我虛構了兩個人物:學生是初入職場的程式設計師——兔小白,老師是有著多年經驗的開發經理——熊小貓。
本書的寫作特色如下。
(1)模擬一對一教學場景。技術圖書通常是作者以第一人稱進行講解的,給我的閱讀感受像是在聽一位老師講課。本書模擬一對一教學場景:我先站在老師的角度講解,透過提問啟發學生;然後切換身份,想像自己作為學生,在聽完這段講解後會提出什麼問題。本書試圖為讀者營造身臨其境地接受一對一教學的感受,在一問一答中探索設計模式的奧秘。
(2)從熟悉的生活場景切入。從日常生活中的小故事開始對每種設計模式進行講解,讓讀者透過身邊熟悉的事物來聯想並了解設計模式。
(3)重現程式設計的演變過程。本書在提出問題後,並不立即使用設計模式解決問題,而是先從直覺化的程式設計開始,逐步演變到如何使用設計模式開發。熊小貓啟發兔小白重構程式的過程正是開發者設計程式時的思考過程。
(4)大量的手繪插畫。在講解關鍵概念時,配以漫畫輔助理解。人腦更樂於接收影像資訊,對影像的記憶長度要遠超文字。幽默風趣的漫畫不僅可以加深印象,而且可以緩解學習時的枯燥感。
(5)獨有的設計手法。設計原則是程式設計的理論基石,設計模式是特定問題的方案總結。二者之間其實還有很多設計小技巧,我稱之為「設計手法」。設計手法不針對特定問題,而是達成設計原則的小技巧,不同的設計模式使用同樣的設計手法。這好比在足球運動中,踢出弧線球是一種技巧,弧線球既可以用在傳球的場景中,也可以用在射門的場景中。
本書內容
軟體需要架構,圖書同樣需要架構。本書的內容架構分為3 個部分。
第一部分為開篇,在正式講解設計模式之前,簡介設計模式和設計原則。
第1 章「設計模式從何而來」,主要介紹設計模式產生的背景。
第2 章「一體式電源與組合式電源——軟體設計原則」,透過設計電腦電源的案例引出六大設計原則。
第二部分進入正題,講解23 種設計模式。
第3 章「想吃漢堡,自己做還是去漢堡店?——簡單工廠模式」,透過兔小白如何取得一個漢堡的例子,引出簡單工廠模式。簡單工廠模式雖然簡單且不在23 種設計模式中,但是表現了多種設計原則。
第4 章「座座工廠平地起——工廠方法模式」,以專精程度更高的廚房為例,引出工廠方法模式。
第5 章「工廠品類要豐富——抽象工廠模式」,透過便利商店更換關東煮供應商的例子,引出抽象工廠模式,並對3 種工廠模式進行比較。
第6 章「組裝電腦的學問——生成器模式」,透過總監負責電腦組裝流程、工人負責具體步驟的例子,講解生成器模式。
第7 章「還記得複製羊桃莉嗎?——原型模式」,透過複製羊的例子,引出原型模式。
第8 章「幹活全靠我一人——單例模式」,透過專案經理身兼數職的例子,講解單例模式。
第9 章「電源插座標準再多也不怕——轉接器模式」,透過電源轉接頭的例子,講解轉接器模式。
第10 章「一橋飛架南北,天塹變通途——橋接模式」,透過遊戲主機和遊戲卡分離的例子,講解橋接模式。
第11 章「樹狀結構也是一種設計模式?——組合模式」,透過公司人力地圖的例子,講解組合模式。
第12 章「人靠衣裝佛靠金裝——裝飾模式」,以美顏相機為例,講解裝飾模式。
第13 章「為什麼加盟速食店越來越多?——面板模式」,透過以加盟模式開速食店的例子,講解面板模式。
第14 章「棋類遊戲中的設計模式——享元模式」,以在消消樂遊戲中如何避免生成大量棋子實例為例,講解享元模式。
第15 章「辦事不必親自出面——代理模式」,以代理辦理簽證為例,講解代理模式。
第16 章「誰來決定需求變更的命運?——職責鏈模式」,以專案的一次需求變更審核為例,講解職責鏈模式。
第17 章「操作再多,也不必手忙腳亂——命令模式」,以專案上線時團隊成員如何配合為例,講解命令模式。
第18 章「點菜也需要翻譯——解譯器模式」,透過飯店點菜終端將鍵盤輸入轉化為點選單的例子,講解解譯器模式。
第19 章「地鐵安檢,誰都逃不掉——迭代器模式」,以地鐵排隊安檢為例,講解迭代器模式,並介紹Java 中的迭代器實現。
第20 章「房產仲介的存在價值——仲介者模式」,以房產仲介在租房業務中的作用為例,講解仲介者模式。
第21 章「管委會通知,每戶必達——觀察者模式」,以管委會發佈通知為例,講解觀察者模式,並介紹Java 中的觀察者模式實現。
第22 章「甲方要求改回第一版——備忘錄模式」,以數次改版演唱會海報設計為例,講解備忘錄模式。
第23 章「狀態改變行為——狀態模式」,以將立體車庫的行為綁定在運行狀態上為例,講解狀態模式。
第24 章「購買手機選項多,如何選購是難題——策略模式」,以根據不同的策略選購手機為例,講解策略模式。
第25 章「遵循策略,不走彎路——範本方法模式」,以自排和手排汽車的起步操作為例,講解範本方法模式。
第26 章「尊重個體差異,提供個性化服務——存取者模式」,以不同等級員工的年終獎計算差異為例,講解存取者模式。
第三部分總結23 種設計模式,提煉設計手法。
第27 章「設計模式總結」,總結了物件導向、設計原則、設計模式三者的關係,並講解從23 種設計模式中提煉出來的10 種設計手法。
建議和回饋
寫書的工作極其瑣碎、繁重,雖然我已盡力確保書中內容的準確性,但由於個人能力有限,難免出現疏漏和瑕疵,歡迎讀者批評指正。
致謝
首先,感謝我的父母。我的父親高中畢業5 年後,在恢復學測的第二年考入大學,從此,知識改變命運的道理深植於他的心中。他非常重視對我的教育,沒有他的培養,就不可能有這本書。我的母親是一位很有耐心的慈母,做任何事情都一絲不苟、追求極致。她的這種品質也一直影響著我,支撐我完成一次次對書稿的修改。
特別感謝我的妻子,沒有她的理解和支持,我不可能完成本書。我寫書的這半年,她承擔起家庭的重任,讓我能專注於寫作。
特別感謝我的兩個孩子,他們時常會關注我的寫作進度,翻看我畫的漫畫,和我說:「等到出版了,送我們一本。」孩子們每天開心的笑容,也是我寫作的動力。
特別感謝我的朋友張龍對我從事技術寫作的影響。感謝Thoughtworks 洞見主編張凱峰在技術寫作和建構影響力上給予我的指導和幫助。
特別感謝在網路上給予我鼓勵的朋友們。沒有你們,我不可能在技術寫作的道路上堅持這麼久。
最後,特別感謝我的編輯張爽。記得那是一個炎熱的下午,我在微信上收到了她的出書邀約。我欣然接受,仿佛看到另一扇門向我敞開。她給予了我很多寫作建議,在她的幫助下,這本書才能順利完成。
感謝每一位幫助過我的家人、朋友和同事⋯⋯
我由衷地希望本書能夠給讀者帶來一些幫助,以反應你們的支持!
李一鳴