模式的模式:從設(shè)計模式到元模式
最近的一兩個月里,我一直在研究各類的模式:設(shè)計模式、架構(gòu)模式、容器模式,以及其它一些特定領(lǐng)域的模式(如并行計算模式)等等。
經(jīng)歷了一番買書、讀論文、讀代碼,我發(fā)現(xiàn)了以前對于模式的理解不夠深刻。也因此呢,這篇文章就是用來記錄一些缺乏的東西,諸如于模式語言、模式的模式等。
PS:為了方便閱讀,本文的書名使用都是簡寫模式,全稱在最后的相關(guān)資料中。
模式重談
為了避免出現(xiàn)類似于 Datum 是最好的語言這一類的問題,在那之前,我得先闡述一下對于模式的看法:
- 模式是對于慣用方式的總結(jié),不限于編程,有相當多的人習慣了使用各種設(shè)計模式,但是他并不知道這是何種模式。它是一個概念字表,用于快速溝通。
- 模式是解決方案,滿足錘子定律,只有遇到特定的問題時,你才會需要它。
- 模式是適用于特定場景的,大部分的模式對于當前所處的系統(tǒng)是無用的,往往只有少數(shù)的模式是適合的。
- 模式是知識體系的展現(xiàn),掌握模式的多少,更多的說明見多識廣,并不一定代表真實的代碼水平和能力。
- 模式需要刻意練習,學習模式是一個漫長的過程,所以總會遇到理解解決、使用錯誤的情況,不要擔心。
- 模式種類繁多,計算機行業(yè)普遍認同的是:模式的起源是亞歷山大的《建筑的永恒之道》。在更早的時間里,也還有對應(yīng)的總結(jié),但是這里是最體系化的技巧。
除了設(shè)計模式之外,我們所處的行業(yè)還有大量的其它模式:
- 容器設(shè)計模式。應(yīng)對于云原生應(yīng)用下一系列復雜的分式場景,Google 的工程師發(fā)表了相關(guān)的論文對此進行總結(jié),常見的有 Sidecar、Adapter、Ambassador 等。
- 架構(gòu)模式。架構(gòu)模式是在給定上下文中解決軟件架構(gòu)中常見問題的通用,可重用的解決方案。除此,一些常見的架構(gòu)風格,如微服務(wù)、事件驅(qū)動架構(gòu)等,從大類上來說也被歸納到架構(gòu)模式中。
- ……
所以,你會發(fā)現(xiàn)這些模式只是人們對于慣用法的總結(jié)。
尋找模式
回過頭來看,當我們會發(fā)現(xiàn)進入一個新的領(lǐng)域,進行相關(guān)領(lǐng)域的架構(gòu)設(shè)計之時,我們會不斷搜尋各類的資料,而后再去貼合到設(shè)計中去。實際上呢,我們是在尋找該領(lǐng)域的模式,有了這些模式,便可以照貓畫虎的設(shè)計一個系統(tǒng),而不會出現(xiàn)太大的問題。
運氣好的情況下,我們甚至于能比在這個領(lǐng)域的大多數(shù)人做得更好 —— 因為我們所掌握的是解決這一類問題的模式。
這時,我們已經(jīng)有一個很有優(yōu)勢性的套路,以幫助我們更好地進入新的領(lǐng)域。但是呢,作為一個新的領(lǐng)域的初來者,往往不知道到底應(yīng)該采用哪一種模式,也不確定模式之間存在何種關(guān)系。
相關(guān)書籍:《設(shè)計模式》
模式歸類:目錄、集合、倉庫
在一個軟件系統(tǒng)中,模式很少獨立存在,往往是多個模式相互組合,用于解決特定的問題。而其中的一種組織方式的模式就是模式集合。隨后,根據(jù)不同的需求,再對進行分門別類。如《POSA 5》所介紹的幾種方式:
- 即時(ad hoc)組織。
- 根據(jù)層次劃分:根據(jù)抽象、粒度和規(guī)模的層次劃分。
- 根據(jù)領(lǐng)域組織:電信、金融、電子商務(wù)等。
- 根據(jù)分區(qū)組織:歸屬于架構(gòu)的哪一部分。如層、階層(tier)、組件和包都是分區(qū)的例子
- 根據(jù)意圖組織:如 POSA、GoF 的 23 種設(shè)計模式、DDD
- ……
接著,讓我們來看幾個分類示例。
設(shè)計模式的組織
在《設(shè)計模式》一書中,引入的概念是『設(shè)計模式空間』,在這里它們被分為了三大類:
- 創(chuàng)建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。
- 結(jié)構(gòu)型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。
- 行為型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式、狀態(tài)模式、策略模式、職責鏈模式、訪問者模式
其劃分的兩條準分別是: 目的準則,用來完成什么工作;范圍準則,指定的模式是用于類還是用于對象。
DDD 的組織
《領(lǐng)域驅(qū)動設(shè)計》一書其中也是一本模式合集,這就是為什么這本書不易于讀懂的原因之一。另外一個原因則是,翻譯這本書的人沒有理解好什么是統(tǒng)一語言。
在 《領(lǐng)域驅(qū)動設(shè)計》 一書以多種形式組織了模式,依次的四個部分是(PS:個人臨時總結(jié)):
- 運用領(lǐng)域模型 —— 『模型知識提取的模式』
- 模型驅(qū)動設(shè)計的構(gòu)造塊 —— 『模型設(shè)計的模式』
- 通過重構(gòu)來加深理解 —— 『模型優(yōu)化的模式』
- 戰(zhàn)略設(shè)計 —— 『模型邊界劃分的模式』
而這個順序其實也是我們在實施 DDD 過程中的設(shè)計過程,而后再進行層次化的組織,如『戰(zhàn)略設(shè)計』部分根據(jù)不同的意圖,又分為不同的合集:
- 保持模型的完整性,如限界上下文、上下文地圖等
- 精煉:核心域、通用域等
- 大型結(jié)構(gòu):演化秩序(Evolving Order)、系統(tǒng)隱喻等
所以從結(jié)構(gòu)上來看,《領(lǐng)域驅(qū)動設(shè)計》是一本由小而大的書,閱讀難度略大,需要一定的經(jīng)驗。
模式分類的意圖
我們把『如何應(yīng)用設(shè)計模式看作是一個問題域』,那么模式分類就是在這個問題域里的一種解決方案。
在計算機的不同的復雜領(lǐng)域里,如并行編程、架構(gòu)設(shè)計等等,它們本身是包含了大量的模式。而有了對于這些模式的進一步分類,對于我們應(yīng)用模式會有更大的幫助 —— 至少在應(yīng)對同一個次級問題時,我們可以尋找可能的替代模式。
不過呢,多數(shù)時候,我們往往不知道的是:我們遇到的問題是什么?
角落里的模式語言
如 《POSA 5》所定義的一樣:模式語言與具體領(lǐng)域高度相關(guān),并且能對這一類系統(tǒng)提供具體而周全的引導,具體包括以下幾項:
- 要解決的主要問題有哪些?
- 這些問題應(yīng)該以什么樣的先后次序解決?
- 解決一個給定問題,有什么可用的替代解決方案?
- 怎樣處理問題之間的依賴性?
在有“周邊” 問題存在的情況下,怎樣最有效地解決單個問題?
簡單來說,模式語言針對于某個特定的問題(如并行編程)所抽象的模式,并包含了他們之間的關(guān)系等,能用于系統(tǒng)性地解決這一類問題。
書中還提到 了 Gerard Meszaros 的觀點“模式語言可以用來指導生手創(chuàng)建系統(tǒng)”。Aha,這不就是我們想要的東西嗎?作為一個進入新領(lǐng)域的新人,我們需要這么一個模式語言。盡管模式語言可以幫助我們解決這一類的問題,但是它也意味著它自身需要:充分覆蓋、進展可持續(xù)、緊密集成。依照這一系列的前提,它意味著設(shè)計這個模式語言的人應(yīng)該是業(yè)內(nèi)專家,并且模式本身應(yīng)該是不斷演進的。
因此,當我們把如何實施和使用模式看作是我們的問題時,那么模式語言解決這一類問題的模式。
分布式計算的模式語言
《POSA》系列大概是在中文世界 里,我們所能找到的最好的資料。因此,這里再次以《POSA 4》作為例子,《POSA 4》全稱是《面向模式的軟件架構(gòu):分布式計算的模式語言》。
先來看圖(圖中的圈內(nèi)表示的是問題域,連續(xù)表示的是他們的關(guān)系,每個問題域下包含了相關(guān)的模式):
POSA Pattern Language
舉例來說開頭的『From Mud to Structure』(從混沌到結(jié)構(gòu))就是一個大的問題域,對應(yīng)于這個問題域則包含了一系列的模式,如:MVC、分層、PAC、微內(nèi)核等。同時,針對于這個問題題來說,如果我們還要數(shù)據(jù)庫訪問,那么我們從數(shù)據(jù)庫訪問中獲得對應(yīng)的模式,以此來完善我們的設(shè)計。
然后,在我們進入了具體的模式/問題域之后,它還詳細介紹了如何實現(xiàn)對應(yīng)的模式。如分層:
POSA Layer
有了這系列的配合,我們便可以完善整個系統(tǒng)的設(shè)計。
微服務(wù)的模式語言
接著,讓我們來看看《微服務(wù)架構(gòu)設(shè)計模式》中關(guān)于微服務(wù)的架構(gòu)模式概述:
微服務(wù)模式語言
從上圖中,我們可以看到由 Chris Richardson 整理的這個微服務(wù)模式語言,對語言進行了多層的分類,并指明了它們之間的關(guān)系。頗為遺憾的是這個模式語言只包含了關(guān)系,缺少了一些相關(guān)關(guān)系的描述。
雖然如此,但是從總體上來說,它還是能在一定程度上幫助我們設(shè)計微服務(wù)。
相關(guān)書籍:《POSA 4》、《POSA 5》、《微服務(wù)架構(gòu)設(shè)計模式》
模式的模式
從模式再模式歸類,再到模式語言,我們已經(jīng)有了整套的方案。最后,我們就剩下一些有意思的問題,諸如于如何發(fā)現(xiàn)新的模式?如何對現(xiàn)有的模式進行一些抽象。
對于『模式的模式』的理解,有助于我們更好地理解好設(shè)計模式。對于設(shè)計模式的理解之后,只需要理解其背后的模式,就不需要再去熟記每個設(shè)計模式。
所以,我們就來到了元素模式,依據(jù)的它也是來自于一本書《元素模式》。
元素模式:設(shè)計模式的模式
模式是來源于對慣用法的總結(jié),而諸如于元素模式則是對于設(shè)計模式的提取,即模式中的模式。元素模式(Elemental Design Patterns)的核心要義是一組面向?qū)ο蟮幕靖拍睢?/p>
對 OO 中的設(shè)計模式進行更細致的拆分,我們就能得到位于其背后的模式。作為其中的核心元素模式便是:創(chuàng)建對象、檢索、繼承和抽象接口。于是,如書上所說,結(jié)合這四個 EDP,我們可以創(chuàng)建對,并實施特定的保證,在運行時建立自此的關(guān)聯(lián),并從一種類型出發(fā)建立其他類型,以及創(chuàng)建出聲明,并帶有關(guān)于未來的、未定的類型的保證。
而我們在實施方法調(diào)用時,也被抽象了四個 EDP:遞歸、委托、重定向和集聚,以此構(gòu)成了設(shè)計的砌塊。
架構(gòu)模式的模式
最后就回到了我想抽象的問題,那么架構(gòu)模式其背后的模式又有什么呢?我試著進行了簡單的拆解:
- 契約。輸入與輸出、API 等。
- 分割。隔離變化、明確職責等。
- 約束。功能需求和非功能需求、性能等。
- 封裝。接口封裝。
- 協(xié)作。協(xié)作風格等
- ……
當然了,我還需要他們進行重新命名,以構(gòu)建在架構(gòu)模式領(lǐng)域的統(tǒng)一語言。
其它
盡管,它有些復雜,但是依舊很有意思。
相關(guān)資料
《元素模式》
《設(shè)計模式》 -> 《設(shè)計模式:可復用面向?qū)ο筌浖幕A(chǔ)》
《POSA 4》 -> 《面向模式的軟件架構(gòu),卷 4:分布式計算的模式語言》
《POSA 5》 -> 《面向模式的軟件架構(gòu),卷 5:模式與模式語言》
《領(lǐng)域驅(qū)動設(shè)計》 -> 《領(lǐng)域驅(qū)動設(shè)計:軟件核心復雜性應(yīng)對之道》
本文轉(zhuǎn)載自微信公眾號「 phodal」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系 phodal公眾號。