Golang - Design Pattern #19: 橋接模式 (Bridge)

更新於 2023/08/29閱讀時間約 7 分鐘
raw-image
🌉 將抽象和實現分離 🌉

在許多複雜的程式設計問題中,如何將抽象與其具體實現分離開來,往往是一個重要的挑戰。橋接模式正是為了解決這樣的問題而生。透過橋接模式 (Bridge Pattern),不僅可以確保抽象和實現在結構上分離,還能提供一套彈性的機制來適應變化。接下來,我們將深入探討這一模式,並學習如何在 Go 語言中實現它。


橋接模式

橋接模式的主要目的是"分離抽象與實現",這樣在兩者獨立變化時,不會互相影響。此模式涉及到一個抽象接口,以及多個實現該接口的具體類。這使得你可以在不修改原始抽象類的情況下,更改或添加新的具體實現。


Go to Code ~~

🎨 不同的畫圖方法

假設我們有一個形狀Shape,它有多種不同的繪製方法(如繪製在螢幕上、打印等)。使用橋接模式,我們可以輕鬆地將Shape和繪製方法分離。


package main

import "fmt"

// DrawingAPI is the abstract "implementation" interface
type DrawingAPI interface {
DrawCircle(radius, x, y float64)
}

// Shape is the abstract "abstraction" class
type Shape interface {
Draw()
}

type CircleShape struct {
x, y, radius float64
drawingAPI DrawingAPI
}

func NewCircle(x, y, radius float64, drawingAPI DrawingAPI) *CircleShape {
return &CircleShape{x: x, y: y, radius: radius, drawingAPI: drawingAPI}
}

func (c *CircleShape) Draw() {
c.drawingAPI.DrawCircle(c.radius, c.x, c.y)
}

type DrawingAPI1 struct{}

func (da *DrawingAPI1) DrawCircle(radius, x, y float64) {
fmt.Printf("API1 draws circle at %f:%f radius %f\n", x, y, radius)
}

type DrawingAPI2 struct{}

func (da *DrawingAPI2) DrawCircle(radius, x, y float64) {
fmt.Printf("API2 draws circle at %f:%f radius %f\n", x, y, radius)
}

func main() {
// Usage
circle1 := NewCircle(1, 2, 3, &DrawingAPI1{})
circle1.Draw() // Output: API1 draws circle at 1.000000:2.000000 radius 3.000000

circle2 := NewCircle(1, 2, 3, &DrawingAPI2{})
circle2.Draw() // Output: API2 draws circle at 1.000000:2.000000 radius 3.000000
}


📩 消息發送

假設我們有一個消息發送系統,其中有不同的消息(如緊急消息、普通消息)和多種發送方式(如SMS、Email)。我們可以使用橋接模式將消息和發送方式分離。


package main

import "fmt"

// MessengerAPI is the abstract "implementation" interface
type MessengerAPI interface {
Send(message string, to string)
}

// Message is the abstract "abstraction" class
type Message interface {
Send()
}

type NormalMessage struct {
content string
to string
method MessengerAPI
}

func NewNormalMessage(content, to string, method MessengerAPI) *NormalMessage {
return &NormalMessage{content: content, to: to, method: method}
}

func (m *NormalMessage) Send() {
m.method.Send(m.content, m.to)
}

type UrgentMessage struct {
content string
to string
method MessengerAPI
}

func NewUrgentMessage(content, to string, method MessengerAPI) *UrgentMessage {
return &UrgentMessage{content: content, to: to, method: method}
}

func (m *UrgentMessage) Send() {
m.method.Send("[Urgent]"+m.content, m.to)
}

type SMSMessenger struct{}

func (sms *SMSMessenger) Send(message, to string) {
fmt.Printf("Sending SMS to %s: %s\n", to, message)
}

type EmailMessenger struct{}

func (email *EmailMessenger) Send(message, to string) {
fmt.Printf("Sending Email to %s: %s\n", to, message)
}

func main() {
// Usage
msg1 := NewNormalMessage("Hello, world!", "John", &SMSMessenger{})
msg1.Send() // Output: Sending SMS to John: Hello, world!

msg2 := NewUrgentMessage("System is down!", "Admin", &EmailMessenger{})
msg2.Send() // Output: Sending Email to Admin: [Urgent]System is down!
}


小結

橋接模式為我們提供了一個結構化的方法,幫助我們有效地分離抽象和實現。透過這一模式,我們可以確保當增加新的實現或修改現有實現時,不會對原有的抽象造成影響。而 Go 語言中的接口使得我們可以輕鬆地應用這一模式,創建高度靈活且可維護的代碼。🛠️

avatar-img
31會員
194內容數
歡迎來到【代碼的詩情】:探索程式語言之美 系列,這是一場優雅的程式之旅,透過詩歌的抒發,尋找不同程式語言的美感和精髓。 在這個系列中,我們將透過文字的韻律,深入探索多種程式語言的核心概念和語法,以及它們獨特的應用和技巧。每一篇詩歌都是一個故事,每一段代碼都是一句詩句,讓代碼的旋律和詩情在其中相互交織。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
KH Huang的沙龍 的其他內容
在軟體開發中,處理nil或空值是一個常見的挑戰。不妥當地處理它們可能導致錯誤,使得程式碼的健壯性下降。但有沒有一種方法,可以讓我們在不做特殊檢查的情況下,優雅地處理這些空值呢?答案是肯定的,那就是空物件模式 (Null Object Pattern)!
創建物件有時是一個資源密集型和耗時的過程,尤其是當涉及到從資料庫或其他來源初始化物件時。原型模式就是為了解決這種問題🔧,它提供了一種方法,能夠通過複製一個已存在的物件來迅速創建新物件,而不是從頭開始。
當我們在處理一連串的事件或請求時,責任鏈模式 (Chain of Responsibility Pattern) 就像一位隱形的助手🤖,幫助我們將這些請求一一分發給合適的處理者。
大家有沒有遇到過這種情況:當應用程式使用過多資源,如記憶體或 CPU 時,整個系統的性能直線下降?😰 不得不說,資源的有效管理在軟體開發中真的超級重要!這就是享元模式 (Flyweight Pattern) 大顯身手的時候了!
你知道那種感覺嗎?當你想從複雜的家電系統中只開啟你的電視和音響,卻需要找一大堆遙控器才能完成。外觀模式(Facade)就是這樣的解決方案!它可以幫助我們簡化複雜系統的操作,提供一個單一、簡單的接口。
你還記得在學校時代,當兩位朋友吵架時,有時會有第三者出來做調解嗎?在程式設計中,我們有一種模式就像那位調解者,幫助兩個物件之間保持距離,這就是仲介者模式( Mediator Pattern )!
在軟體開發中,處理nil或空值是一個常見的挑戰。不妥當地處理它們可能導致錯誤,使得程式碼的健壯性下降。但有沒有一種方法,可以讓我們在不做特殊檢查的情況下,優雅地處理這些空值呢?答案是肯定的,那就是空物件模式 (Null Object Pattern)!
創建物件有時是一個資源密集型和耗時的過程,尤其是當涉及到從資料庫或其他來源初始化物件時。原型模式就是為了解決這種問題🔧,它提供了一種方法,能夠通過複製一個已存在的物件來迅速創建新物件,而不是從頭開始。
當我們在處理一連串的事件或請求時,責任鏈模式 (Chain of Responsibility Pattern) 就像一位隱形的助手🤖,幫助我們將這些請求一一分發給合適的處理者。
大家有沒有遇到過這種情況:當應用程式使用過多資源,如記憶體或 CPU 時,整個系統的性能直線下降?😰 不得不說,資源的有效管理在軟體開發中真的超級重要!這就是享元模式 (Flyweight Pattern) 大顯身手的時候了!
你知道那種感覺嗎?當你想從複雜的家電系統中只開啟你的電視和音響,卻需要找一大堆遙控器才能完成。外觀模式(Facade)就是這樣的解決方案!它可以幫助我們簡化複雜系統的操作,提供一個單一、簡單的接口。
你還記得在學校時代,當兩位朋友吵架時,有時會有第三者出來做調解嗎?在程式設計中,我們有一種模式就像那位調解者,幫助兩個物件之間保持距離,這就是仲介者模式( Mediator Pattern )!
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
Thumbnail
👨‍💻簡介 Go 語言有各種資料型別,分為基本型別和複合型別。基本型別包括: 整數、浮點數、布林值、字串 複合型別包括: 陣列、片段、結構、函式、對映、通道、介面 等。 整數型別 整數型別有許多種,像是 int8、int16、int32、int64。我們可以依據實際需求選擇。
Thumbnail
跟團住在號稱5星級飯店,SONO CALM GOYANG HOTEL 出發前在網路上找不到相關資料,google附近的地圖失真,於是來發一篇文 沒拍房間內部,房間還蠻大的,兩張單人床中間兩旁都有空間可以走動,開放式衣架,備品有小瓶沐浴乳、洗髮精、潤髮乳,都是濃濃的薄荷味,如果不能接受的話,最好自
Thumbnail
這篇文章將會講述常用圖檔的檔案格式差異、比較和應用。
Thumbnail
Side Project 是打破傳說魔咒的解咒法,對於新鮮人來說,要找工作大多都要求工作經驗,然而這就跟打副本需要至少兩次刷副本的經驗一樣,若在團隊中沒有熟人,永遠會卡在等級一。
Web design Agency Miracle Hong Kong understands the importance of a website design that works and converts your target audience into customers. We hav
Thumbnail
從服務生小姐到藝術家,從飲食色彩活動到個人篆刻特展,我很榮幸身邊有一位跟我一樣關注飲食與人,熱愛自我探索、享受實驗驗證過程的好朋友 -蔡大暇
Thumbnail
建議先看過Golang 入門這篇再閱讀這篇! 使用Go官方提供的net/http library就能建立http web伺服器囉!
Thumbnail
遙想當年初探 Regular Expression,腦袋紮紮實實地被凌虐了一番,同時十分敬佩把正規表示式寫的簡潔有力又精確無誤的神人。最近學校在上編譯器課程,估計近期內便會接觸到不少 RegExp 的技巧,於是就來寫篇筆記吧~
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
Thumbnail
👨‍💻簡介 Go 語言有各種資料型別,分為基本型別和複合型別。基本型別包括: 整數、浮點數、布林值、字串 複合型別包括: 陣列、片段、結構、函式、對映、通道、介面 等。 整數型別 整數型別有許多種,像是 int8、int16、int32、int64。我們可以依據實際需求選擇。
Thumbnail
跟團住在號稱5星級飯店,SONO CALM GOYANG HOTEL 出發前在網路上找不到相關資料,google附近的地圖失真,於是來發一篇文 沒拍房間內部,房間還蠻大的,兩張單人床中間兩旁都有空間可以走動,開放式衣架,備品有小瓶沐浴乳、洗髮精、潤髮乳,都是濃濃的薄荷味,如果不能接受的話,最好自
Thumbnail
這篇文章將會講述常用圖檔的檔案格式差異、比較和應用。
Thumbnail
Side Project 是打破傳說魔咒的解咒法,對於新鮮人來說,要找工作大多都要求工作經驗,然而這就跟打副本需要至少兩次刷副本的經驗一樣,若在團隊中沒有熟人,永遠會卡在等級一。
Web design Agency Miracle Hong Kong understands the importance of a website design that works and converts your target audience into customers. We hav
Thumbnail
從服務生小姐到藝術家,從飲食色彩活動到個人篆刻特展,我很榮幸身邊有一位跟我一樣關注飲食與人,熱愛自我探索、享受實驗驗證過程的好朋友 -蔡大暇
Thumbnail
建議先看過Golang 入門這篇再閱讀這篇! 使用Go官方提供的net/http library就能建立http web伺服器囉!
Thumbnail
遙想當年初探 Regular Expression,腦袋紮紮實實地被凌虐了一番,同時十分敬佩把正規表示式寫的簡潔有力又精確無誤的神人。最近學校在上編譯器課程,估計近期內便會接觸到不少 RegExp 的技巧,於是就來寫篇筆記吧~