👣 操作物件結構 👣
訪問者模式 (Visitor Pattern) 是一種設計模式,它允許開發者將新的操作新增到現有物件結構中,而不必修改該結構的內部代碼。該模式的重點是將操作和物件結構分離,提供一個彈性的方式新增新的行為。
訪問者模式主要涉及兩種接口:Visitor
和Element
。Visitor
接口定義了訪問不同類型物件的方法,而Element
接口定義了accept()
方法,該方法接受一個訪問者作為參數。
假設我們的電子商務平台有多種產品,我們想為每種產品計算折扣。而不同的產品,折扣方式可能不同。
// 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)
}
訪問者模式是一種強大的設計模式,它允許開發者輕鬆地為物件結構新增新的操作,而無需修改結構本身。這提供了增加新行為的極大靈活性,同時保持物件結構的簡潔性。這種分離和靈活性在開發大型和複雜的系統時尤其有用,因為它可以幫助確