Golang - Design Pattern #20: 訪問者模式 (Visitor)

更新於 發佈於 閱讀時間約 6 分鐘
raw-image
👣 操作物件結構 👣

訪問者模式 (Visitor Pattern) 是一種設計模式,它允許開發者將新的操作新增到現有物件結構中,而不必修改該結構的內部代碼。該模式的重點是將操作和物件結構分離,提供一個彈性的方式新增新的行為。


訪問者模式

訪問者模式主要涉及兩種接口:VisitorElementVisitor接口定義了訪問不同類型物件的方法,而Element接口定義了accept()方法,該方法接受一個訪問者作為參數。


Go Go Go


🛒 電子商務系統

假設我們的電子商務平台有多種產品,我們想為每種產品計算折扣。而不同的產品,折扣方式可能不同。


// You can edit this code!
// Click here and start typing.
package main

import "fmt"

// Element
type Product interface {
Accept(visitor Visitor)
}

// Concrete Elements
type Book struct {
price float64
title string
}

func (b *Book) Accept(visitor Visitor) {
visitor.VisitBook(b)
}

type Fruit struct {
price float64
name string
weight float64
}

func (f *Fruit) Accept(visitor Visitor) {
visitor.VisitFruit(f)
}

// Visitor
type Visitor interface {
VisitBook(book *Book)
VisitFruit(fruit *Fruit)
}

// Concrete Visitor
type DiscountVisitor struct{}

func (d *DiscountVisitor) VisitBook(book *Book) {
discountPrice := book.price * 0.9
fmt.Printf("Discounted price for book '%s': %f\n", book.title, discountPrice)
}

func (d *DiscountVisitor) VisitFruit(fruit *Fruit) {
discountPrice := fruit.price * 0.85
fmt.Printf("Discounted price for %s: %f\n", fruit.name, discountPrice)
}

func main() {
// Client code
book := &Book{price: 100, title: "Design Patterns"}
fruit := &Fruit{price: 50, name: "Apple", weight: 0.5}

discountVisitor := &DiscountVisitor{}

book.Accept(discountVisitor) // Discounted price for book 'Design Patterns': 90.000000
fruit.Accept(discountVisitor) // Discounted price for Apple: 42.500000

}


✉️ 使用者反饋系統

假設我們有一個使用者反饋系統,我們想要對不同類型的反饋執行不同的操作,例如保存到資料庫或發送電子郵件提醒。


package main

// Element
type Feedback interface {
Accept(visitor FeedbackVisitor)
}

// Concrete Elements
type Comment struct {
content string
userID int
}

func (c *Comment) Accept(visitor FeedbackVisitor) {
visitor.VisitComment(c)
}

type Report struct {
description string
severity int
}

func (r *Report) Accept(visitor FeedbackVisitor) {
visitor.VisitReport(r)
}

// Visitor
type FeedbackVisitor interface {
VisitComment(comment *Comment)
VisitReport(report *Report)
}

// Concrete Visitor
type DatabaseSaver struct{}

func (d *DatabaseSaver) VisitComment(comment *Comment) {
// Logic to save comment to database
}

func (d *DatabaseSaver) VisitReport(report *Report) {
// Logic to save report to database and maybe send an email alert
}

func main() {
// Client code
comment := &Comment{content: "Great product!", userID: 101}
report := &Report{description: "Bug found in checkout process.", severity: 1}

saver := &DatabaseSaver{}

comment.Accept(saver)
report.Accept(saver)
}


小結 📚

訪問者模式是一種強大的設計模式,它允許開發者輕鬆地為物件結構新增新的操作,而無需修改結構本身。這提供了增加新行為的極大靈活性,同時保持物件結構的簡潔性。這種分離和靈活性在開發大型和複雜的系統時尤其有用,因為它可以幫助確

留言
avatar-img
留言分享你的想法!
avatar-img
KH Huang的沙龍
36會員
194內容數
歡迎來到【代碼的詩情】:探索程式語言之美 系列,這是一場優雅的程式之旅,透過詩歌的抒發,尋找不同程式語言的美感和精髓。 在這個系列中,我們將透過文字的韻律,深入探索多種程式語言的核心概念和語法,以及它們獨特的應用和技巧。每一篇詩歌都是一個故事,每一段代碼都是一句詩句,讓代碼的旋律和詩情在其中相互交織。
KH Huang的沙龍的其他內容
2023/09/06
嗨!今天我們來深入探討鏈式方法模式,也就是讓你可以一路連續調用方法,看起來好像在鏈接它們似的。那麼,讓我們馬上進入主題吧!
Thumbnail
2023/09/06
嗨!今天我們來深入探討鏈式方法模式,也就是讓你可以一路連續調用方法,看起來好像在鏈接它們似的。那麼,讓我們馬上進入主題吧!
Thumbnail
2023/09/03
嗨,大家好!今天我們來聊聊什麼是延遲評估模式,它的好處是啥,還有在 Go 裡面是怎麼玩的。
Thumbnail
2023/09/03
嗨,大家好!今天我們來聊聊什麼是延遲評估模式,它的好處是啥,還有在 Go 裡面是怎麼玩的。
Thumbnail
2023/09/03
在許多大型系統中,不同的子系統需要共享和修改某些資訊以達到一個共同目的。在這種情況下,傳統的方法可能會造成混亂和冗餘。這時,黑板模式出現了,它提供了一個統一的架構,讓這些子系統可以有效率地協作。
Thumbnail
2023/09/03
在許多大型系統中,不同的子系統需要共享和修改某些資訊以達到一個共同目的。在這種情況下,傳統的方法可能會造成混亂和冗餘。這時,黑板模式出現了,它提供了一個統一的架構,讓這些子系統可以有效率地協作。
Thumbnail
看更多
你可能也想看
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
嗨!今天我們來深入探討鏈式方法模式,也就是讓你可以一路連續調用方法,看起來好像在鏈接它們似的。那麼,讓我們馬上進入主題吧!
Thumbnail
嗨!今天我們來深入探討鏈式方法模式,也就是讓你可以一路連續調用方法,看起來好像在鏈接它們似的。那麼,讓我們馬上進入主題吧!
Thumbnail
👨‍💻簡介 在Go語言中,Interface 是一個重要且強大的概念。Interface提供了一種方式來定義對象之間的契約,讓你可以設計更具有靈活性和可擴展性的程式碼。 你可以把Interface想像成是一種約定,讓不同的東西彼此溝通的方式變得特別靈活和好擴充,告訴程式裡的各個元件彼此要怎麼合作
Thumbnail
👨‍💻簡介 在Go語言中,Interface 是一個重要且強大的概念。Interface提供了一種方式來定義對象之間的契約,讓你可以設計更具有靈活性和可擴展性的程式碼。 你可以把Interface想像成是一種約定,讓不同的東西彼此溝通的方式變得特別靈活和好擴充,告訴程式裡的各個元件彼此要怎麼合作
Thumbnail
訪問者模式 (Visitor Pattern) 是一種設計模式,它允許開發者將新的操作新增到現有物件結構中,而不必修改該結構的內部代碼。該模式的重點是將操作和物件結構分離,提供一個彈性的方式新增新的行為。
Thumbnail
訪問者模式 (Visitor Pattern) 是一種設計模式,它允許開發者將新的操作新增到現有物件結構中,而不必修改該結構的內部代碼。該模式的重點是將操作和物件結構分離,提供一個彈性的方式新增新的行為。
Thumbnail
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
Thumbnail
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
Thumbnail
在軟體開發中,處理nil或空值是一個常見的挑戰。不妥當地處理它們可能導致錯誤,使得程式碼的健壯性下降。但有沒有一種方法,可以讓我們在不做特殊檢查的情況下,優雅地處理這些空值呢?答案是肯定的,那就是空物件模式 (Null Object Pattern)!
Thumbnail
在軟體開發中,處理nil或空值是一個常見的挑戰。不妥當地處理它們可能導致錯誤,使得程式碼的健壯性下降。但有沒有一種方法,可以讓我們在不做特殊檢查的情況下,優雅地處理這些空值呢?答案是肯定的,那就是空物件模式 (Null Object Pattern)!
Thumbnail
創建物件有時是一個資源密集型和耗時的過程,尤其是當涉及到從資料庫或其他來源初始化物件時。原型模式就是為了解決這種問題🔧,它提供了一種方法,能夠通過複製一個已存在的物件來迅速創建新物件,而不是從頭開始。
Thumbnail
創建物件有時是一個資源密集型和耗時的過程,尤其是當涉及到從資料庫或其他來源初始化物件時。原型模式就是為了解決這種問題🔧,它提供了一種方法,能夠通過複製一個已存在的物件來迅速創建新物件,而不是從頭開始。
Thumbnail
大家有沒有遇到過這種情況:當應用程式使用過多資源,如記憶體或 CPU 時,整個系統的性能直線下降?😰 不得不說,資源的有效管理在軟體開發中真的超級重要!這就是享元模式 (Flyweight Pattern) 大顯身手的時候了!
Thumbnail
大家有沒有遇到過這種情況:當應用程式使用過多資源,如記憶體或 CPU 時,整個系統的性能直線下降?😰 不得不說,資源的有效管理在軟體開發中真的超級重要!這就是享元模式 (Flyweight Pattern) 大顯身手的時候了!
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News