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

更新於 發佈於 閱讀時間約 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
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
每間公司都會有其一套商業模式,透過商業模式,可以知道我們客群為何、從哪裡獲取收益
Thumbnail
未來一定是個人品牌的市場,透過整合資源,建立營利商業模式,持續行銷創新並擁有強大業務部隊、財務和法律力量,才可能為你帶來成功。
「01 需求方是誰? 02 需求方想要什麼? 03 滿足對方欲求的供給方是誰? 04 供給方有什麼先入為主的觀念? 05 新概念是什麼? 06 新概念能提供的價值本質是什麼? 07 因為這個新概念,需求方與供給方達到的新的理想關係是什麼? 08 理想的新業態是什麼?」
Thumbnail
實際就業後,會發現收集與分析需求,通常都不是工程師在做,會有另一群人,以非工程的角度收集及分析需求,然後在開發過程中蹦出不同的火花,於是很好奇另一群人的想法是什麼?我不敢說這本書能完全代表另一群人的想法,但確實能夠得到很多有用的思維。推薦給所有的軟體工程師。
Thumbnail
本書介紹了戰略設計、管理領域複雜度、實際應用領域驅動設計等主題。透過對核心子領域、支持子領域、限界上下文等概念的探討,提供了領域驅動設計的相關知識。這篇文章中還涉及了微服務、事件驅動架構和資料網格等相關主題,提供了設計系統和應用領域驅動設計的指導。
Thumbnail
觀察者模式透過主題訂閱/訊息通知的機制,極度增強系統的可擴展性、靈活性以及降低組件間的耦合度。概念直觀簡單,是非常實用的設計模式。
Thumbnail
代理模式通過封裝原始對象來實現對該對象的控制和管理,同時不改變原始對象的行為或客戶端與該對象互動的方式,以此介入或增強對該對象的訪問和操作。
Thumbnail
策略模式將多種演算法封裝於獨立的策略類別中,每個策略類別都實現了一個共同的介面。這種設計允許使用者在系統運行時動態選擇和切換演算法,以達成相同的目的。
Thumbnail
程式設計中不可或缺的一部分 介面是使用者與程式互動的媒介,因此介面的設計會影響使用者的體驗和感受。一個清晰明白、易懂的介面,可以讓使用者輕鬆地使用程式,並獲得良好的使用體驗。 需要與程式設計師密切溝通 設計師需要了解程式的功能和需求,並根據使用者的習慣和需求進行設計。設計師和程式設計師之間的溝
Thumbnail
替產業做設計 有人要我談程式設計,那我就稍微談一下。我從事的大都是產業的工作,所以我們也從如何替產業做設計來談起。基本上,每個產業都會有自己的作業流程,大同小異。但是基礎來做都是一樣的,都會有客戶、物料、產品、供應商、員工等資料。不同的是,由於企業型態的不同,他們每個人有不同的作業流程。這個作業流
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
每間公司都會有其一套商業模式,透過商業模式,可以知道我們客群為何、從哪裡獲取收益
Thumbnail
未來一定是個人品牌的市場,透過整合資源,建立營利商業模式,持續行銷創新並擁有強大業務部隊、財務和法律力量,才可能為你帶來成功。
「01 需求方是誰? 02 需求方想要什麼? 03 滿足對方欲求的供給方是誰? 04 供給方有什麼先入為主的觀念? 05 新概念是什麼? 06 新概念能提供的價值本質是什麼? 07 因為這個新概念,需求方與供給方達到的新的理想關係是什麼? 08 理想的新業態是什麼?」
Thumbnail
實際就業後,會發現收集與分析需求,通常都不是工程師在做,會有另一群人,以非工程的角度收集及分析需求,然後在開發過程中蹦出不同的火花,於是很好奇另一群人的想法是什麼?我不敢說這本書能完全代表另一群人的想法,但確實能夠得到很多有用的思維。推薦給所有的軟體工程師。
Thumbnail
本書介紹了戰略設計、管理領域複雜度、實際應用領域驅動設計等主題。透過對核心子領域、支持子領域、限界上下文等概念的探討,提供了領域驅動設計的相關知識。這篇文章中還涉及了微服務、事件驅動架構和資料網格等相關主題,提供了設計系統和應用領域驅動設計的指導。
Thumbnail
觀察者模式透過主題訂閱/訊息通知的機制,極度增強系統的可擴展性、靈活性以及降低組件間的耦合度。概念直觀簡單,是非常實用的設計模式。
Thumbnail
代理模式通過封裝原始對象來實現對該對象的控制和管理,同時不改變原始對象的行為或客戶端與該對象互動的方式,以此介入或增強對該對象的訪問和操作。
Thumbnail
策略模式將多種演算法封裝於獨立的策略類別中,每個策略類別都實現了一個共同的介面。這種設計允許使用者在系統運行時動態選擇和切換演算法,以達成相同的目的。
Thumbnail
程式設計中不可或缺的一部分 介面是使用者與程式互動的媒介,因此介面的設計會影響使用者的體驗和感受。一個清晰明白、易懂的介面,可以讓使用者輕鬆地使用程式,並獲得良好的使用體驗。 需要與程式設計師密切溝通 設計師需要了解程式的功能和需求,並根據使用者的習慣和需求進行設計。設計師和程式設計師之間的溝
Thumbnail
替產業做設計 有人要我談程式設計,那我就稍微談一下。我從事的大都是產業的工作,所以我們也從如何替產業做設計來談起。基本上,每個產業都會有自己的作業流程,大同小異。但是基礎來做都是一樣的,都會有客戶、物料、產品、供應商、員工等資料。不同的是,由於企業型態的不同,他們每個人有不同的作業流程。這個作業流