Design Pattern

Design Pattern

  • 一般軟體圈講的設計模式是指 GoF (「四人幫設計模式」(Gang of Four) 的23個 design pattern ,而 GoF 的23個設計模式全名是 object oriented design pattern,所以設計模式是指在物件導向基礎上的一套設計原則,但這些設計原則也不是 GoF 憑空想出來的,而是結合前人的經驗整理總結出來的一套原則,是一套檢驗過、行之有效的方法
  • 描述在各種不同情況下,要怎麼解決問題的一種方案
  • 核心概念就是,讓程式碼更有彈性並更有利用性

在軟體工程中,設計模式(design pattern)是對軟體設計中普遍存在(反覆出現)的各種問題,所提出的解決方案。這個術語是由埃里希·伽瑪(Erich Gamma)等人在1990年代從建築設計領域引入到電腦科學的。

設計模式並不直接用來完成程式碼的編寫,而是描述在各種不同情況下,要怎麼解決問題的一種方案。物件導向設計模式通常以類別或物件來描述其中的關係和相互作用,但不涉及用來完成應用程式的特定類別或物件。設計模式能使不穩定依賴於相對穩定、具體依賴於相對抽象,避免會引起麻煩的緊耦合,以增強軟體設計面對並適應變化的能力。

並非所有的軟體模式都是設計模式,設計模式特指軟體「設計」層次上的問題。還有其他非設計模式的模式,如架構模式。同時,演算法不能算是一種設計模式,因為演算法主要是用來解決計算上的問題,而非設計上的問題。

– by wikipedia 設計模式 (電腦)

  • 簡單來說,就是利用一些技巧,來使得程式碼的可重用性變高,可擴充性與彈性較好

object oriented design pattern

Creational Patterns 【創建型(生成)模式】:

  • 在軟體工程中,是處理物件創建機制的設計模式。此類型模式試圖根據適合的情況來決定建立物件。單純的物件創建常會導致一些設計問題或增加設計的複雜度。創建型模式則藉由控制物件的生成方式來解決這問題。
  • Factory (工廠模式):
    • Simple Factory (簡單工廠模式)
      • Simple Factory模式又稱Static Factory模式。一個Simple Factory生產成品,而對客戶端隱藏產品產生的細節,物件如何生成,生成前是否與其它物件建立依賴關係,客戶端皆不用理會,用以將物件生成方式之變化 與客戶端程式碼隔離。
    • Abstract Factory (抽象工廠模式):為一個產品族提供了統一的創建介面。當需要這個產品族的某一系列的時候,可以從抽象工廠中選出相應的系列創建一個具體的工廠類。
      • 目的 : 使程式能輕易的 Port 到另外一個系統上。
      • 使用時機:為要建立一個容易 update , 可移植性高的系統時。
    • Factory Method (工廠方法模式) :定義一個介面用於創建對象,但是讓子類決定初始化哪個類。工廠方法把一個類的初始化下放到子類。
      • 目的 : 當 Factory 無法預期以後會需要什麼樣的 component 時,使用 Factory Method ,將責任延遲到 concreteProcuct 身上。簡單地說,如果您希望如何建立父類別中用到的物件這件事,是由子類別來決定,可以使用 Factory Method。
      • 使用時機:在目標功能尚無法決定或可能變化時使用之。
  • Builder (建造者模式):將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
    • 乍看之下,Builder模式與 Abstract Factory 模式 很類似,其中最主要的差別在於,Abstract Factory模式著重在不同的工廠實作提供不同的一組產品給組件使用,產品之間並不見得有「部份」(Part of)的概念
    • 目的 : Client 不斷呼叫 Builder 建立 component 直到建立完整的 complex component 才呼叫 Builder 傳回 complex component。
    • 使用時機:在設計多目標,多樣的彈性系統時,或目標樣式尚未決定時使用之。
  • Prototype (原型模式): 用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。
    • 目的 : 讓 object 來擔任建立與自己相同型態的 object的任務。
    • 使用時機:在設計者無法預期以後會有何種物件,且未來維護者可能無能力或無法加入新的物件到物件管理程式之中時。
  • Singleton (獨身模式或叫單例模式):確保一個類只有一個實例,並提供對該實例的全局訪問。
    • active
    • lazy
    • Double ChockLock
  • Registry of Singleton
    • 目的 : 讓一個 class 只能有一個 instance。

Structural Patterns 【結構模式】:

  • 藉由一以貫之的方式來了解元件間的關係,以簡化設計。
  • Adapter (配接器模式):將某個類的介面轉換成客戶端期望的另一個介面表示。適配器模式可以消除由於介面不匹配所造成的類兼容性問題。

    • 目的 : 把別人的物件整合到自己的 interface 中。
    • 使用時機:when two incompatible classes should work together。
    • Default Adapter
    • Object Adapter
    • Class Adapter
  • Bridge (橋樑模式):將一個抽象與實現解耦,以便兩者可以獨立的變化。

    • 目的 : 把 interface 與 implementation 分開使其互不影響。
    • 使用時機:在設計前用來隔開 user , user interface, object interface 與 implementation。
  • Composite (組合模式):把多個對象組成樹狀結構來表示局部與整體,這樣用戶可以一樣的對待單個對象和對象的組合。

    • 目的 : 遞回定義的物件
    • 使用時機: 對於結構複雜的物件,但介面一致的物件使用之。具有層次性或組合性的物件可以使用Composite模式
  • Decorator (裝飾模式):向某個對象動態地添加更多的功能。修飾模式是除類繼承外另一種擴展功能的方法。其不採取繼承的方式,而以組合的方式動態地為物 件添加功能

    • 目的 : 使附屬功能能以簡單的繼承方式一層層的套疊上去。
    • 使用時機:要附加功能又不用破壞原來的架構的情況下。
  • Facade (外觀模式):為子系統中的一組介面提供一個一致的界面, 外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。您可以檢視應用程式使用這些程式庫的方式,釐出一個入口(Facade)介面,讓對程式庫的依賴實現在對介面的實作上

    • 目的:提供一整組物件對外的介面,以統一對外界面並達到 loose couple 的功能。
    • 使用時機:為在系統太複雜的時候,作為整合之用。
  • Flyweight (享元模式):通過共享以便有效的支持大量小顆粒對象。對於小且可以資訊重複的物件,可以考慮共用

    • 目的:利用物件共享的方式以節省實體空間。
    • 使用時機:許多物件都會包含同一物件許多次的時候使用之。
  • Proxy (代理模式):為其他對象提供一個代理以控制對這個對象的訪問。根據您的目的不同,您的代理物件將負有不同的責任,因而產生多種不 同的代理情況

    • 目的:作為其它物件的存取門戶。
    • 使用時機:物件因為存取時間太長,或重複存取次數太多,或有可能根本不會存取到時使用。

Behavioral Patterns 【行為模式】:

  • 用來識別對象之間的常用交流模式並加以實現。如此,可在進行這些交流活動時增強彈性。
  • Chain of Responsibility (責任鏈模式):

    • 為解除請求的發送者和接收者之間耦合,而使多個對象都有機會處理這個請求。將這些對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個對象處理它。
  • Command (命令模式):

    • 將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可取消的操作。
    • 其主要精神在於將指令的建立與執行分離
  • Iterator (迭代器模式):

    • 提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示。
  • Strategy (策略模式):

    • 定義一個演算法的系列,將其各個分裝,並且使他們有交互性。策略模式使得演算法在用戶使用的時候能獨立的改變。
    • Strategy模式著重在服務細節或演算流程的封裝,將服務與演算法封裝為一個個的Strategy物件,讓使用服務或演算法的客戶端可以依需求抽換服務或演算法,而不用關心服務或演算法的實作方式
  • Template Method (模版方法模式):

    • 模板方法模式準備一個抽象類,將部分邏輯以具體方法及具體構造子類的形式實現,然後聲明一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。先構建一個頂級邏輯框架,而將邏輯的細節留給具體的子類去實現。
    • 其在抽象父類別中定義好某個操作的整體流程,而在子類別中才將流程中一些未定的操作實現出來
  • Observer (觀察者模式):

    • 在對象間定義一個一對多的聯繫性,由此當一個對象改變了狀態,所有其他相關的對象會被通知並且自動刷新。
  • Mediator (中介者模式):

    • Mediator模式用一個中介的物件來封裝物件彼此之間的交互,物件之間並不用互相知道另一方,這可以降低物件之間的耦合性,如果要改變物件之間的交互行為,也只需要對Mediator加以修改即可。
    • 包裝了一系列對象相互作用的方式,使得這些對象不必相互明顯作用,從而使它們可以鬆散偶合。當某些對象之間的作用發生改變時,不會立即影響其他的一些對象之間的作用,保證這些作用可以彼此獨立的變化。
  • State (狀態模式):

    • 可以考慮讓每個狀態各自成為一個物件,負責自己該狀態的服務,並提供切 換狀態的方法
    • 讓一個對象在其內部狀態改變的時候,其行為也隨之改變。狀態模式需要對每一個系統可能取得的狀態創立一個狀態類的子類。當系統的狀態變化時,系統便改變所選的子類。
  • Memento (備忘錄模式):

    • 備忘錄對象是一個用來存儲另外一個對象內部狀態的快照的對象。備忘錄模式的用意是在不破壞封裝的條件下,將一個對象的狀態捉住,並外部化,存儲起來,從而可以在將來合適的時候把這個對象還原到存儲起來的狀態。
  • Visitor (訪問者模式):

    • 封裝一些施加於某種資料結構元素之上的操作。一旦這些操作需要修改,接受這個操作的資料結構可以保持不變。訪問者模式適用於資料結構相對未定的系統,它把資料結構和作用於結構上的操作之間的耦合解脫開,使得操作集合可以相對自由的演化。
    • 是將演算流程與所操作的物件之特定結構分離,這樣分離之後,針對特定物件的操作部份將集中在Visitor中管理,並可以隨時修 改操作。
  • Interpreter (解譯器模式):

    • 給定一個語言, 定義它的文法的一種表示,並定義一個解釋器, 該解釋器使用該表示來解釋語言中的句子。

Others

sidecar pattern

MVC

  • Model、View、Controller 的區分,是希望能把應用程式的內部運作歸納成不同的部門,讓每個部門各自負責不同的關注點。具體的行為是「把不同意義的程式碼放在不同的檔案裡」。

model

  • Model
    • 常譯為「模型」,負責和資料庫溝通。這裡我們要先注意:應用程式和資料庫是兩個不同的東西,在應用程式裡想要做「新增/瀏覽/修改/刪除」的動作,就需要先有 Model 層幫忙去資料庫裡取出必要的資料,把資料放進應用程式裡的某個程式物件,然後才能用 JavaScript 去操作該物件。
    • Model 管理的功能層被稱做「邏輯層」,更明確一點說,是和「商業邏輯」有關的功能
  • View
    • 常譯為「視圖」,View 所管理的功能層叫作「表現層 (presentation layer)」,顧名思義是負責管理畫面的呈現,也就是 HTML 樣板 (template)。
    • 因為 HTML template 會有需要以動態顯示資料的情況 (也就是由 Model 取出的資料內容),所以 View 會再進一步運用樣板引擎 (template engine) 將資料帶入 template。我們很快就會在實作中看到相關細節。
  • Controller
    • 常譯為「控制器」,它掌握使用者互動邏輯,也是應用程式收發 request/response 的核心。
    • 來自路由的 request 會先被送到 Controller,再由 Controller 通知 Model 調度資料,並且把資料傳遞給 View 來產生樣板 (template),並將呈現資料的 HTML 頁面回傳給客戶端。
    • 在 Controller 上會設置很多不同的「動作 (action)」,有點類似電視遙控器上的按鈕,只要觸發了不同的 action,Controller 就會啟動後續一系列的行為。
    • 採用 MVC 架構三大好處
  • 重複使用已寫好的程式碼:由於 MVC 三塊彼此獨立、各司其職,你可以使用同一套 model,針對使用場景不一樣,產出不同的 view 來呈現適合的資料,最大化程式碼的使用效率。
  • 更容易維護程式碼:由於 MVC 三塊彼此獨立且互不干擾,可以讓你在不破壞現有架構下,進行擴充或修改,大幅提升開發效率。
  • 方便團隊合作:同先前所說,由於 MVC 架構將應用程式切分為三塊,在實際工作時,也可以比照相同的方式,將工程師、設計師的負責部分切開,加快開發速度。

flux

Reference