設計模式與程式架構(七)

更新於 2024/06/18閱讀時間約 6 分鐘

※ 生產者和消費者模式

定義:

生產者和消費者在同一時間內共同存取某一個資料空間。生產者負責生成數據並將其放入共享空間,消費者負責從共享空間中取走數據進行處理。兩者之間互不相干,也不須互相知道對方的存在。

  • 共同存取資料空間:生產者和消費者共享同一個資料空間。這個空間通常是緩衝區或隊列,用於在它們之間傳遞數據。
  • 生產者和消費者的操作:
  1. 生產者:負責生成數據並將其放入共享空間。
  2. 消費者:負責從共享空間中取走數據並進行處理。
  • 互不相干:生產者和消費者彼此獨立運作,彼此之間不需要了解對方的存在或狀態。它們之間的唯一通信方式是通過共享的資料空間。

優點:

  • 生產者與消費者之間完全解耦合:
  1. 生產者和消費者彼此獨立,互不依賴,只通過共享的資料空間進行通信。
  2. 這種解耦提高了系統的靈活性和可擴展性,使得系統更容易維護和擴展。例如,可以獨立地增加或減少生產者或消費者的數量。
  • 在多線程的系統架構中依然容易實作:
  1. 生產者/消費者模式簡化了多線程環境下的數據傳遞和協作。
  2. 通常使用緩衝區或隊列來實現這種模式,可以有效避免線程間的競爭條件,確保數據一致性和系統穩定性。

※ 什麼是 Message Queue(MQ)?

定義:

Message Queue (MQ),又稱為消息佇列,是一種訊息傳遞仲介。在這種架構中,生產者(Producer)生成並發送消息,仲介(Broker)管理和傳遞消息,消費者(Consumer)接收並處理消息。消息佇列提供了不同程序或不同系統之間的非同步溝通

優點:

  • 非同步溝通生產者和消費者可以用不同的速度工作,彼此不需要等待對方完成操作。
  • 系統解耦生產者和消費者之間不直接通信,而是通過消息佇列進行間接通信,這提高了系統的靈活性和可維護性。
  • 暫存容錯當消費者(Consumer)意外關閉或出現故障時,未處理完的消息會暫存在消息佇列(MQ)中,並不會丟失。這些消息可以在消費者重啟後繼續處理。這種特性確保了系統的穩定性和可恢復性。
  • 可靠性消息佇列通常具有消息持久化和重試機制,確保消息不會丟失。
  • 水平擴展Producer和Consumer:Producer 可以分散在不同來源、裝置收集(例如 IoT (物聯網)應用);Consumer 可以按照需求和資源,運行在多台機器上,加速訊息(任務)的消化和處理。
  • 可擴展性可以輕鬆地增加更多的生產者或消費者來應對負載變化,保持系統的高效運行。

常用套件:

  • RabbitMQ:是一個支持多種主流程式語言的消息佇列系統。例如:Node.js、Golang、Java、C/C++,Python。
  • Redis:是一個流行的開源內存資料庫,被廣泛用作快取(cache)和儲存服務。它特別適合需要快速存取和高效處理數據的應用場景。 特別是和Node.js 的結合能夠為應用帶來高效的數據處理和管理能力。

※ 簡單的生產者-消費者模式的實現範例解說

const buffer = <any>[] //用一個array當作是緩衝區
const MAX_BUFFER = 10 //緩衝區最大上限

//設一個生產者
class Producer {
private buffer: any[]
//告訴它buffer
constructor(buffer: any[]) {
this.buffer = buffer
}
//產生一個容易被發現的內容
random = () => String(~(Math.random() * 1000)).padStart(3, "0")
start = () => {
//使用 setInterval 定時器
setInterval(() => {
//每秒產生消息往緩衝區塞資料
if (this.buffer.length >= MAX_BUFFER)
return console.warn("緩衝區已滿,請稍等")
//產生message的內容
const msg = "內容" + this.random()
console.log("產生" + msg)
//將資料放進buffer
this.buffer.push(msg)
}, 1000)
}
}
//設一個消費者
class Consumer {
private buffer: any[]
constructor(buffer: any[]) {
this.buffer = buffer
}
start = () => {
setInterval(() => {
//消費者往緩衝區拿資料
if (this.buffer.length <= 0) return console.warn("緩衝區已空,請稍等")

//將資料取出來處理
const msg = this.buffer.shift()
console.log("取出", msg, "來處理")
}, 1200)
}
}
//緩衝區監控器來偵測buffer內的資料有哪些
const buffer_monitor = setInterval(() => {
console.log("--> 緩衝區目前有", buffer.length, "筆資料")
}, 500)

//建立生產者和消費者實例,並將共享的 buffer 傳遞給它們
const producer = new Producer(buffer)
const consumer = new Consumer(buffer)

// 啟動生產者和消費者
producer.start()
consumer.start()
/**--> 緩衝區目前有 0 筆資料
產生內容-684
--> 緩衝區目前有 1 筆資料
取出 內容-684 來處理
--> 緩衝區目前有 0 筆資料
產生內容-380
--> 緩衝區目前有 1 筆資料
取出 內容-380 來處理
-->不斷產出資料直到terminal結束/*



    全端網頁開發專業知識分享
    留言0
    查看全部
    avatar-img
    發表第一個留言支持創作者!
    ※ 觀察者模式 定義: 觀察者模式(Observer Pattern)是一種設計模式,涉及兩個主要角色:觀察者(Observers)和被觀察者(Subject)。在這種模式中,一群觀察者訂閱並觀察某個被觀察的對象。當被觀察者的狀態發生改變時,它會通知所有觀察者,讓他們知曉並作出相應的反應。這種模
    ※ 工廠模式 定義: 工廠模式是一種實現了「工廠」概念的物件導向設計模式。它提供一個通用的工廠介面,將創建instance(實例)的程式碼交由子類別各自實現,並根據需求去動態地生成相應的物件。這種模式將物件的創建邏輯與使用邏輯分開,使程式碼更容易維護和擴展。 特點: 具有高度標準化和同質性的
    ※ 單例模式介紹 ※ 定義:單例模式是一種設計模式,確保一個class(類)只有一個實例,並提供一個存取它的全域存取點。無論如何取值,皆只對這個實例取值。 ※ 目的:保證一個類別只會產生一個物件,而且提供存取該物件的統一方法。 ※ 講解:單例模式確保一個類無論怎麼 new 或 get,都只能拿
    ※ 設計模式的五大精神介紹(S.O.L.I.D): ※ 第一大精神 — S:單一職責原則(Single responsibility principle, SRP) ※ 定義: 每個物件,不管是類別或函數,都應該只負責一項功能。 當需求改變時,僅需改相關的區域,而不需要更動其他不相關的部分
    ※ TypeScript範例說明: interface ITest { test1: string test2: number print: (arg: string[]) => boolean } class Test implements ITest { public te
    ※ 何謂Typescript? Typescript是Microsoft開發出來的一種JavaScript的擴展程式語言。 ※ 為什麼選擇 TypeScript? 靜態型別: 在執行程式碼之前就能避免許多錯誤。 幫助開發人員更快發現型別使用上的問題。 有效提升開發應用程式的效率。 輕鬆
    ※ 觀察者模式 定義: 觀察者模式(Observer Pattern)是一種設計模式,涉及兩個主要角色:觀察者(Observers)和被觀察者(Subject)。在這種模式中,一群觀察者訂閱並觀察某個被觀察的對象。當被觀察者的狀態發生改變時,它會通知所有觀察者,讓他們知曉並作出相應的反應。這種模
    ※ 工廠模式 定義: 工廠模式是一種實現了「工廠」概念的物件導向設計模式。它提供一個通用的工廠介面,將創建instance(實例)的程式碼交由子類別各自實現,並根據需求去動態地生成相應的物件。這種模式將物件的創建邏輯與使用邏輯分開,使程式碼更容易維護和擴展。 特點: 具有高度標準化和同質性的
    ※ 單例模式介紹 ※ 定義:單例模式是一種設計模式,確保一個class(類)只有一個實例,並提供一個存取它的全域存取點。無論如何取值,皆只對這個實例取值。 ※ 目的:保證一個類別只會產生一個物件,而且提供存取該物件的統一方法。 ※ 講解:單例模式確保一個類無論怎麼 new 或 get,都只能拿
    ※ 設計模式的五大精神介紹(S.O.L.I.D): ※ 第一大精神 — S:單一職責原則(Single responsibility principle, SRP) ※ 定義: 每個物件,不管是類別或函數,都應該只負責一項功能。 當需求改變時,僅需改相關的區域,而不需要更動其他不相關的部分
    ※ TypeScript範例說明: interface ITest { test1: string test2: number print: (arg: string[]) => boolean } class Test implements ITest { public te
    ※ 何謂Typescript? Typescript是Microsoft開發出來的一種JavaScript的擴展程式語言。 ※ 為什麼選擇 TypeScript? 靜態型別: 在執行程式碼之前就能避免許多錯誤。 幫助開發人員更快發現型別使用上的問題。 有效提升開發應用程式的效率。 輕鬆
    你可能也想看
    Google News 追蹤
    Thumbnail
    *合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
    VIPER(View Interactor Presenter Entities Router) View 負責顯示資料。 Interactor 負責管理model。 Presenter 負責處理View的業務邏輯。 Entities 負責data model。
    MVVMC(Model View ViewModel Coordinator),特點是Coordinator。 Model 負責儲存應用程式的資料。 View 負責顯示資料。 ViewModel 負責處理View和Model之間的狀態關係。 Coordinator 負
    MVI(Model View Intent),特點是Intent。 Model 負責介面狀態 View 負責顯示資料。 Intent 負責將封裝後的操作告知Model。
    MVVM(Model View ViewModel),特點是View跟ViewModel之間做資料綁定。 Model 負責儲存應用程式的資料。 View 負責顯示資料。 ViewModel 負責處理View和Model之間的狀態關係。
    MVP(Model View Presenter)由MVC演變而來。MVC與MVP的差異是View跟Model之間的關係;MVC中是可以直接溝通的;MVP中是不可以直接溝通的,必須要透過 Presenter。 Model 負責資料存取。 View 負責顯示資料,並將使用者的操作傳給P
    Thumbnail
    代理模式通過封裝原始對象來實現對該對象的控制和管理,同時不改變原始對象的行為或客戶端與該對象互動的方式,以此介入或增強對該對象的訪問和操作。
    Thumbnail
    策略模式將多種演算法封裝於獨立的策略類別中,每個策略類別都實現了一個共同的介面。這種設計允許使用者在系統運行時動態選擇和切換演算法,以達成相同的目的。
    MVC是一種物件導向設計模式,將應用程式分成Model、View和Controller。是在1979年被提出,主要是要解決下列問題: 維護「長存儲存媒體」(Persistent Storage)的資料 維護執行流程的邏輯控制 顯示使用者所需的資訊和使用介面 Model 實作儲存應用程式
    Thumbnail
    所有的 CSS 設計模式都是為了維持可讀性、好維護、易擴充這幾個目標,今天就來談談 BEM 設計模式,並搭配 Sass 中的 SCSS 來介紹,並探討在各種情境下該如何使用 BEM。
    Thumbnail
    小心設計模式別亂用 📷 介紹 設計模式就是過去的人,根據常見的軟體設計的問題,提出的解決方案。 設計模式總共有23種,根據情境分成三大類型,建立型、結構型、行為型。 建立型模式(Creational Patterns) 簡單工廠(Simple Factory) 工廠方法(Factory) 抽象工廠
    Thumbnail
    *合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
    VIPER(View Interactor Presenter Entities Router) View 負責顯示資料。 Interactor 負責管理model。 Presenter 負責處理View的業務邏輯。 Entities 負責data model。
    MVVMC(Model View ViewModel Coordinator),特點是Coordinator。 Model 負責儲存應用程式的資料。 View 負責顯示資料。 ViewModel 負責處理View和Model之間的狀態關係。 Coordinator 負
    MVI(Model View Intent),特點是Intent。 Model 負責介面狀態 View 負責顯示資料。 Intent 負責將封裝後的操作告知Model。
    MVVM(Model View ViewModel),特點是View跟ViewModel之間做資料綁定。 Model 負責儲存應用程式的資料。 View 負責顯示資料。 ViewModel 負責處理View和Model之間的狀態關係。
    MVP(Model View Presenter)由MVC演變而來。MVC與MVP的差異是View跟Model之間的關係;MVC中是可以直接溝通的;MVP中是不可以直接溝通的,必須要透過 Presenter。 Model 負責資料存取。 View 負責顯示資料,並將使用者的操作傳給P
    Thumbnail
    代理模式通過封裝原始對象來實現對該對象的控制和管理,同時不改變原始對象的行為或客戶端與該對象互動的方式,以此介入或增強對該對象的訪問和操作。
    Thumbnail
    策略模式將多種演算法封裝於獨立的策略類別中,每個策略類別都實現了一個共同的介面。這種設計允許使用者在系統運行時動態選擇和切換演算法,以達成相同的目的。
    MVC是一種物件導向設計模式,將應用程式分成Model、View和Controller。是在1979年被提出,主要是要解決下列問題: 維護「長存儲存媒體」(Persistent Storage)的資料 維護執行流程的邏輯控制 顯示使用者所需的資訊和使用介面 Model 實作儲存應用程式
    Thumbnail
    所有的 CSS 設計模式都是為了維持可讀性、好維護、易擴充這幾個目標,今天就來談談 BEM 設計模式,並搭配 Sass 中的 SCSS 來介紹,並探討在各種情境下該如何使用 BEM。
    Thumbnail
    小心設計模式別亂用 📷 介紹 設計模式就是過去的人,根據常見的軟體設計的問題,提出的解決方案。 設計模式總共有23種,根據情境分成三大類型,建立型、結構型、行為型。 建立型模式(Creational Patterns) 簡單工廠(Simple Factory) 工廠方法(Factory) 抽象工廠