軟體設計的質、門、道
模式
提起設計模式,免不了要提一提那位離經叛道的劍橋建築系學生—— Christopher Alexander。他的著作《建築的永恆之道》以建築學為名,探討了這個宇宙最本質的哲學問題(GoF 也打得一手好廣告)。
這個世界的事物有其固有的結構,而其形態卻是千變萬化,我們無法全盤掌握。但萬變不離其宗,我們可以通過理解這些變化背後更加深層穩定的實質來應對各種變化。
Alexander 提出了一個理解事物結構的新視角——模式。何謂模式,可以通過 Alexander 的原話來理解——
每個模式描述了一個在我們周圍不斷重複發生的問題及該問題解決方案的核心。這樣,你就能一次又一次的使用該方案而不必做重複工作。
每個模式都是一個由三部分組成的規則,它表達的是某一環境、一個問題以及解決問題的方案之間的關係。
作為世界中的元素,每一個模式都是這三者之間的關係:某一環境、此環境中反覆出現的某個因素系統以及使用這些因素能夠自我協調的某種空間配置。
模式可以幫助我們辨認或設計事物。以軟體領域的資料庫為例,我們之所以認為某一個中間件是「資料庫」,並不是因為它的名稱、規模、生產商,而是因為其最本質的特徵:數據的讀、寫、存儲。無論其表現形式為何,如緩存、關係型資料庫、文檔型資料庫、文件系統等,只要其滿足資料庫的本質特徵(符合資料庫的模式),我們都可以認為它是資料庫。而一個資料庫的穩定結構就是讀介面、寫介面、存儲媒介以及它們之間的關係,其它的任何擴展優化都是圍繞著這個結構和關係進行的。而這些結構中的每一部分又由更小的結構和關係組成。當我們實現了一個符合這種模式的中間件,也可以宣稱我們實現了一個資料庫。
《建築的永恆之道》提出質、門、道三個基本概念:無名之質、有形之門、永恆之道。在其之上建立的設計原則,可以適用於任何工程學科的設計,包括軟體工程。
無名之質:軟體的特性
Alexander 說,「存在著一個極為重要的特質,它是人、城市、建築或荒野的生命與精神的根本準則。這種特質客觀明確,但卻無法命名」。嗯,這一特質是絕對客觀的、精確的,以至於無法用人類的辭彙來命名。所以 Alexander 只能用 7 個詞語來描繪這一特質:、、、、、、,這 7 個詞語單獨任何一個都無法描述這一特質,但它們結合起來可以無限接近。這一特質給人以滿足感,並最終改善人類的生活,Alexander 認為設計師須不斷努力,以創造出符合這一特質的建築結構。
可以結合老子(注意發音)的話來理解一下,「無名天地之始,有名萬物之母」。無名,世界的一切尚未被領會、尚未被命名,世界處於一種原初的混沌狀態,即天地之始;有名,事物一旦被領會、被命名,就標誌著萬物歸位,世界開啟,即萬物之母。
從「無名」到「有名」實際上是『人腦』界定一個客觀實體的過程。注意,這裡的『人腦』並非特指人類的大腦,可能是任何形式的「觀察者」。老子認為,實體無法與其環境分割。要界定一個實體,需要給它定一個界限,實體只有被界定後,才會在『人腦』中產生概念,這就是「名」。而實體一旦被界定,也就不再是原始的那個實體了。且依「界限」或「觀察者」不同,其「名」可能也會不同。
這裡頗有一種微觀粒子的量子行為「波粒二象性」的意味。Alexander 的「無名之質」,就是老子的「無名」。當我們試圖以『人腦』來理解無名之質時,就會將其局限在不同的場景中,此時這個無名的「質」就變成了可以定義的「質」,如:整體性、完備性、和諧性、舒適性、可變性、持久性、開放性、可塑性、可居住性等。
在軟體工程中,我們可以將、、、、、、、、、、等特性理解為軟體的「質」,和 Alexander 的建築學觀點一樣,軟體的設計製作也須不斷努力,以達成和完善這些特性為目標。另外,軟體的特性不僅僅存在於軟體本身,也存在於軟體和周邊環境——包括其它軟硬體、計算機外部世界、用戶等——的相互作用中。這種相互作用類似於中國傳統的「風水學」,軟體只有與其環境達成一個和諧的整體,其特性才會得到更好的保障。
有形之門:軟體的模式
「為達到無名特質,我們接著必須建立一種有活力的模式語言作為大門。」如果無名之質是以哲學角度定義了「什麼是建築」,那有形之門則涉及了「如何建築」的理論體系。
建築物各個部分根據一定的關係連接,構成了一定的關係網,這個關係網限定了這種建築的風格、功能等特性。如天安門以木結構為框架,榫卯結合,承重與圍護結構分離,屋頂一條正脊和四條垂脊形成一個垂直的三角形牆面,這種建築結構就形成了中國古代「歇山式」的建築風格。
不獨是建築領域,人們生活中的一系列事物及活動都有其特定的模式,如詩詞的平仄規則形成其特有的韻律;音樂的主副歌、節奏快慢的安排形成悅耳的旋律;文章圖文內容的排版形成特定的文體;日常的衣食住行、娛樂、工作等遵循一定的邏輯或日程安排。「每一個模式就是一個規則,它描述了產生它所限定的整體,你所必須要做的事情。」也即是說,模式描述的並非實體,而是實體之間的關係。
具體到軟體工程中,我們可以將有形之門中的「門」理解為實現軟體特性的法門、途徑、工具,而「形」則是這些法門、途徑、工具的組織形式。《莊子疏》:「氣聚而有其形,氣散而歸於無形也。」這裡的「氣」也就是「門」,而將「氣」聚成的「形」就是模式。根據不同的尺度,可以將「氣」或「門」理解為代碼語句;類和對象;組件或中間件。相應的,代碼語句組成的「形」就是代碼模式,類和對象組成的「形」就是設計模式,組件或中間件組成的「形」就是架構模式。
永恆之道:軟體的設計
Alexander 主張:「在自然界中,一個實體總是作為一個整體出生、發展的。」這像極了老子「道生一,一生二,二生三,三生萬物」的道家思想。一個軟體的設計通常也遵循這一原則:從整體架構出發,通過對功能、性能的劃分,形成各個模塊,再將模塊細化為類、方法等。好的軟體通常蘊含著好的模式,要設計好的軟體需要發現、收集、創造好的模式,而這一過程也即是軟體設計的永恆之道。
《建築的永恆之道》講述的其實就是「自然規律」。利用一系列自然界固有的規則,使人造建築對內達到平衡,對外散發生命力。而這些「自然界固有的規則」放到軟體工程領域就是那一條條我們耳熟能詳的設計原則。當我們遵循利用這些原則,組合拼裝,形成某種特定的前所未見的關係,而這種關係能用來解決某類特定問題,也就意味著一個新的設計模式的誕生。
開-閉原則(Open-Closed Principle, OCP)
里氏代換原則(Liskov Substitution Principle, LSP)
依賴倒置原則(Dependency Inversion Principle, DIP)
介面隔離原則(Interface Segregation Principle, ISP)
單一職責原則(Single Responsibility Principle, SRP)
合成/聚合復用原則(Composite/Aggregate Reuse Principle, CARP)
迪米特法則(Law of Demeter, LoD)
上述是面向對象設計的常見原則,事實上用於指導軟體設計的原則還有很多,如 KISS、DRY、CQS、YAGNI 等。這些原則都是軟體行業長期經驗總結出來的知識,每個軟體開發人員都應該了解,但也不能教條主義,使用時要考慮實際情況。
總結
簡而言之,在軟體工程領域,模式就是用於解決某類具有特定抽象特點的問題的套路。同時,藉助模式的定義,軟體開發人員之間也可以更方便的溝通,比如我說「建立一種對象與對象之間的關係,當一個對象狀態發生變化時自動通知其它對象,其它對象做出相應的反應」。你可能會一頭霧水或者想抽我,但當我說「觀察者模式」時,你立即就能知道我說的是什麼。
設計模式被引入軟體工程領域已經有幾十年,GoF 的設計模式最早成書於 1994 年,如今已知的設計模式早已不止那 23 種,編程語言又經過了這麼多年的發展,一些模式已被融入到編程語言本身,甚至有更好的替代方式。我們應該將設計模式當做一種指導思想,而不是解決問題的具體方案。學習、使用過程中舉一反三,靈活變通,避免教條。在利用設計模式彌補設計不足的同時,也要避免過度設計或模式痴迷,在軟體的迭代開發階段以功能實現為主,當軟體迭代到一定程度時,再使用合適的方法對代碼進行重構,此時便可以從一個相對宏觀的視角觀察總結代碼,從而演化出合適的模式。
本文章系列名為《設計模式註疏》,試圖解釋並以示例的形式實現已知的設計模式,包括 GoF 最早闡述的 23 種模式,以及其它的一些具有代表性的模式。既是「註疏」,便是在前人的基礎上總結、思考、梳理,所謂登得高望得遠,感謝前人的工作。
本文鏈接:http://kweny.io/design-patterns-research-overview/
版權聲明:除非特別說明,本站內容均為原創,轉載請註明出處:K棧-《[設計模式註疏] 軟體設計的質、門、道》。
※流式處理:使用 Apache Kafka的Streams API 實現 Rabobank 的實時財務告警
TAG:K棧IO |