什麼是設計模式 (Design Pattern)? 設計模式系列文 (上)

--

前言

由於碩士班研究很大一部分都以設計模式 (Design Pattern) 為主軸,在軟體工程領域,設計模式也是在開發上非常重要的參考工具,能有效提升軟體的品質、並縮短開發時間。今年初 (2020年) 小弟順利在 AsianPLoP 2020 (Hillside Group PLoP 系列之一,是 Patterns 研究領域的重要會議,AsianPLoP 收錄於 ACM Digital Library) 會議中發表 Pattern 的論文,並經歷了完整 Shepherding (有點類似投期刊時會有的反覆審稿修改的過程) 的過程。而對設計模式的了解,大大幫助我在學術研究上,以及構思問題的解決方案時,很有效且細膩的方式,也大大的訓練並提升我的邏輯思考能力。因此,想透過整理自己在設計模式研究的經驗,深入淺出的把他分享給大家。

本系列 (設計模式系列)文章不限於資訊背景,而希望幫助有意投入設計模式的研究者、從設計模式中獲得系統設計上問題解決方法的開發人員或是對設計模式有興趣的同學,提供一種基於特定情境思考問題與解決方法的方式。本系列文章將分為三部分:「什麼是設計模式?」、「如何撰寫自己的設計模式?」與「如何完善自己的設計模式?」,而各個部分主要會參考兩本不同的書與論文:

  1. Pattern-Oriented Software Architecture (以下稱之為 POSA): Pattern 入門者,與軟體從業人員必讀的書 (據我的研究所老闆說是軟工的聖經之一) 這本書不只針對設計模式做整理,也完整的對其他層級的模式 (例如:架構模式) 做完成的整理。
  2. The Language of Shepherding:Pattern 撰寫與發表 (參與 Pattern 有關論文會議時,必讀文章),從 Pattern 作者與 Pattern 的審稿人角度,描述在 Pattern 產出與發表的過程中,兩者如何幫助 Pattern 更完善與全面。

Pattern 歷史

Pattern (模式)最早源自於建築界的 Christopher Alexander,其出版的書籍 The Timeless Way of Building (1979)說明了 Pattern 如何用於房屋的建造,爾後,Erich Gamma 等人 (俗稱 四人幫, GoF),首先於 1994 年發表了物件導向程式的 Pattern 書籍:Design Patterns — Elements of Reusable Object-Oriented Software,而設計模式在軟體工程領域也隨之蓬勃發展。目前 Pattern 最重要的學術組織為 Hillside Group,其下的 PLoP、EuroPLoP、AsianPLoP 也是 Pattern 領域的重要會議。

什麼是設計模式?

模式 (Pattern),以一句話來解釋:

描述在特定情境 (Context)下,解決設計問題 (Problem) 的最佳實踐 。

而模式中所提出的解決方案 (Solution) 經過多次的驗證,能提供發人員在類似情境下遭遇相關問題時的設計指引,並幫助其釐清問題的脈絡。

而在軟體工程領域中,除了也將 Pattern 分為:

  1. Architecture Patterns:解決軟體系統架構層面的問題。如:MVC (Model-View-Controller pattern) 架構,Layer等等
  2. Design Patterns:提供了改善軟體系統中子系統與元件 (components)的方案。軟工中常見的模式如:Observer,Facade,Adapter等等
  3. Idioms:是一種 lowest-level patterns,為 Programming (程式撰寫)層級提供程式改善方案,主要透過程式語言的解決方案來實現。

範例

POSA 所提的一個經典的案例

情境:每個人都喜歡坐窗邊,有低矮的大窗台與舒適的椅子,若一個房間沒有如此的環境,很難讓你感到舒服。

而你的問題 (Problem) 正是「如何讓你感到舒服自在?」

當你長時間待在這樣的房間,將會有兩種力 (Force) 困擾著你:

  1. 你想要舒服的坐下
  2. 你想要面向窗戶

但其實兩個力 (Force) 可能會常常相互衝突:

  1. 舒服的椅子背對窗戶
  2. 面對窗戶只有一張壞掉的椅子

而最好的方法就是當你每次在設計室內佈局的時候,雖然房間可能沒有太多這樣擺設的選擇,但至少依循著擁有著一個「面對窗戶並有舒服椅子的位子」這樣的模式。

如何描述設計模式?

設計模式的發表雖然也是學術的一環,但其講求的重點與一般學術論文大相逕庭,一般學術論文寫講求深入嚴謹,有些甚至摻雜著艱深的詞彙,因此常使得不是很熟悉該領域或研究的人無法很快的讀懂該論文的脈絡與要表達的意思;而相反的設計模式更像是一個產品的說明書,需要以淺顯易懂的方式來描述,開發人員由於時間有限,需要在短時間內評估該設計模式是否能夠對應相關情境並能有效解決設計上的問題,因此,設計模式更需要以高度結構性的方法與淺顯易懂的行文來表達。

設計模式的結構性描述方法有很多種,小弟我看了不少 PLoP 系列的論文,每篇論文用來描述的方式與架構都不太一樣,但多數的論文會參照 POSA 的描述方式,因此本文主要也介紹 POSA 中,設計模式的描述結構。

Name:

Name 其實是一個是讀者了解 Pattern 最快的方法,也是總結一個 Pattern 的重要方式。而要對 Pattern 命名有很多種方法,常見的像 (1) 取自 Solution 的抽象特徵,例如:Adapter 模式 (像一個轉接器,轉介不同規格的物品)、Observer 模式 (像一個觀察者,若訂閱的標的有狀態的變化,則馬上通知訂閱者) (2)取自 Solution 中元件的名稱,像是 MVC (取自系統中的 Model,View,Controller 三個元件的頭一個字母)

Context:

舉出模式可能適用的情況。主要是利用整理 Problem 可能發生的情境來界定 Problem 可能發生的範圍。雖然 Context 不能列出所有可能的情境,但至少能提供重要的指引。

Problem:

Problem 是描述會在 Context 中重複發生的問題。另外一方面,Problem 也是 Pattern 的核心元素,說明主要模式的設計議題。

Problem 中有一個很重要的元素:Force。在本文上述的範例中有提到,Force 是導致設計問題中存在的具體的力,同時,Force 幫助在 Context 中具體形塑出 Solution 的邊界 (如下圖)。主要列出幾個需要解決的層面:(1)Solution 需要滿足的要求; (2) Solution 需要考慮的限制;(3)Solution 需要包含的特性。而不幸的是,Force 常常是相互矛盾或相互衝突的,在設計Solution時常常需要權衡不同的 Force 來得到最合適的解決方案。

Solution:

以高階的方式描述 Pattern 解決方案原理。Solution 提供解決重複發生的 Problem 的方法,並盡可能平衡相關的 Force (上面提到Force常常是互相矛盾的)。另一方面,Solution 又以 Structure (像是以 UML 類別圖描述各個類別元件之間的關係)Dynamics (像是以 UML 的循序圖描述元件之間的動態行為與協作)層面來描述 Pattern 中不同元件之間的靜態關聯與動態協作。

Implementation:

引導讀者實作 Pattern。此部分可以依照 Pattern 描述的需求採用,並適當提供實作範例 (如:程式碼等等),通常提供與 Example 部分相關的實作方案。

Example:

透過舉實際案例來補足在 Solution 與 Implementation 部分沒有被涵蓋但又為解決方案中重要的層面。

Variants:

此部分可以依照 Pattern 描述的需求採用。簡述 Pattern 相關變形的其他 Pattern。

Known uses:

列舉與 Pattern 相關的現存的系統。這部分很重要,用來證明提出的 Pattern 是真實世界中相關情境存在的設計問題,Pattern的解決方案已被應用且能有效的幫助問題的解決。

Consequences:

列舉 Pattern 的優劣勢。一個 Pattern 不可能是完全完美,因此也需要列出在特定情境下可能造成的限制或缺陷。

Related patterns:

列舉用來解決相似情境下的設計問題或是能與該 Pattern 整合協作的其他Pattern。

總結

這篇文章大略介紹了設計模式的概念、歷史與其描述方式。若在現實生活中遇到任何問題,其實也可以照著 Pattern 的脈絡一步步的思考,先描述問題發生的情境,再定義目前所面臨的問題,盡量列舉出影響該問題發生的所有作用力,最後依循著列舉出的作用力,一一的設計對應的解決方法,這樣就能有效的幫助問題的解決。

若讀者想要更進階的整理或發展自己的設計模式,甚至在 Pattern 相關會議中投稿,可以參考下一篇本系列文的中篇下篇:「如何撰寫自己的設計模式?」與「如何完善自己的設計模式?

💁 延伸閱讀

非常感謝讀完本篇文章,希望本文能對你有些幫助,記得按拍手給我一些鼓勵,Medium 文章中一個人最多能按 50 下 XDD

喜歡我的文章的話也歡迎訂閱我的mediumfacebook,我會定期分享關於軟體工程的知識,還有在日本工作與生活的心得。

--

--

Shun's Blog | 東京開發者生活
Shun's Blog | 東京開發者生活

Written by Shun's Blog | 東京開發者生活

東京涉谷IT企業軟體工程師 | 日本生活、軟體技術、科技趨勢、區塊鏈技術分享

No responses yet