更新於 2024/08/29閱讀時間約 6 分鐘

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

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)
}


小結 📚

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

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.