成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go設計模式--訪客模式

開發 前端
訪客模式也叫訪問者模式(Visitor Pattern)是一種將數據結構對象與數據操作分離的設計模式,可以在不改變數據結構對象類結構的前提下定義作用于這些對象的新的操作, 屬于行為型設計模式。

大家好,這里是每周都在陪你一起進步的網管~!今天繼續學習設計模式—訪客模式

訪客模式也叫訪問者模式(Visitor Pattern)是一種將數據結構對象與數據操作分離的設計模式,可以在不改變數據結構對象類結構的前提下定義作用于這些對象的新的操作, 屬于行為型設計模式。

訪問者模式主要適用于以下應用場景:

  1. 數據結構穩定,作用于數據結構的操作經常變化的場景。
  2. 需要數據結構與數據操作分離的場景。
  3. 需要對不同數據類型(元素)進行操作,而不使用分支判斷具體類型的場景。

訪客模式怎么工作?

訪問者模式通過將算法與對象結構分離來工作,這里說的算法指的是對對象的操作。為此,我們需要定義了一個表示算法的接口--Visitor。該接口將為對象結構中的每個類(一般稱為元素類)提供一個方法。每個方法都將元素類的一個實例作為參數。表示對象結構的所有元素類也會實現一個Element接口,該接口定義了接受訪問者的方法Accpet。此方法將訪問者接口的實現作為參數。當Accpet方法被調用時,訪問者實例對應的方法就會被調用,通過訪問者完成對元素類實例的操作。

下面我們看一下訪問者模式的類結構。

訪客模式結構

訪問者的類結構可以用下面的UML類圖來表示:

圖片

  • 訪客接口 (Visitor) 聲明了一系列以表示對象結構的具體元素為參數的訪問者方法。 如果編程語言支持重載, 這些方法的名稱可以是相同的, 但是其參數一定是不同的。
  • 具體訪客 (Concrete Visitor) 會為不同的具體元素類實現相同行為的幾個不同版本。
  • 元素 (Element) 接口,聲明了一個方法來 “接收” 訪問者。 該方法必須有一個參數被聲明為訪問者接口類型。
  • 具體元素 (Concrete Element) 必須實現接收方法。 該方法的目的是根據當前元素類將其調用重定向到相應訪問者的方法。 請注意, 即使元素基類實現了該方法, 所有子類都必須對其進行重寫并調用訪客對象中的合適方法。

訪客模式代碼示例

在這個用訪客模式實現不同維度的訂單統計的例子里,假設我們建設了一個訂單管理系統, 現在系統中要求能按照不同維度統計分析銷售訂單

  • 區域銷售報表: 需按銷售區域, 統計銷售情況
  • 品類銷售報表: 需根據不同產品, 統計銷售情況

以后還有可能增加其他維度的銷售統計報表,針對這個需求我們可以根據訪問者模式, 可將不同的報表, 設計為訂單的訪問者。 首先定義訂單實體和它要實現的Element接口

"本文使用的完整可運行源碼
去公眾號「網管叨bi叨」發送【設計模式】即可領取"
// 訂單服務接口
type IOrderService interface {
Save(order *Order) error
// 有的教程里把接收 visitor 實現的方法名定義成 Accept
Accept(visitor IOrderVisitor)
}


// 訂單實體類,實現IOrderService 接口
type Order struct {
ID int
Customer string
City string
Product string
Quantity int
}

func (mo *OrderService) Save(o *Order) error {
mo.orders[o.ID] = o
return nil
}

func (mo *OrderService) Accept(visitor IOrderVisitor) {
for _, v := range mo.orders {
visitor.Visit(v)
}
}

func NewOrder(id int, customer string, city string, product string, quantity int) *Order {
return &Order{
id, customer,city,product,quantity,
}
}

接下來定義生成各種銷售報表的訪客類,以及它們實現的訪客接口

"本文使用的完整可運行源碼
去公眾號「網管叨bi叨」發送【設計模式】即可領取"
type IOrderVisitor interface {
// 這里參數不能定義成 IOrderService
Visit(order *Order)
Report()
}

type CityVisitor struct {
cities map[string]int
}

func (cv *CityVisitor) Visit(o *Order) {
n, ok := cv.cities[o.City]
if ok {
cv.cities[o.City] = n + o.Quantity
} else {
cv.cities[o.City] = o.Quantity
}
}

func (cv *CityVisitor) Report() {
for k,v := range cv.cities {
fmt.Printf("city=%s, sum=%v\n", k, v)
}
}

func NewCityVisitor() IOrderVisitor {
return &CityVisitor{
cities: make(map[string]int, 0),
}
}

// 品類銷售報表, 按產品匯總銷售情況, 實現ISaleOrderVisitor接口
type ProductVisitor struct {
products map[string]int
}

func (pv *ProductVisitor) Visit(it *Order) {
n,ok := pv.products[it.Product]
if ok {
pv.products[it.Product] = n + it.Quantity
} else {
pv.products[it.Product] = it.Quantity
}
}

func (pv *ProductVisitor) Report() {
for k,v := range pv.products {
fmt.Printf("product=%s, sum=%v\n", k, v)
}
}

func NewProductVisitor() IOrderVisitor {
return &ProductVisitor{
products: make(map[string]int,0),
}
}

最后我們嘗試使用Vistor生成各種銷售報表

func main() {
orderService := NewOrderService()
orderService.Save(NewOrder(1, "張三", "廣州", "電視", 10))
orderService.Save(NewOrder(2, "李四", "深圳", "冰箱", 20))
orderService.Save(NewOrder(3, "王五", "東莞", "空調", 30))
orderService.Save(NewOrder(4, "張三三", "廣州", "空調", 10))
orderService.Save(NewOrder(5, "李四四", "深圳", "電視", 20))
orderService.Save(NewOrder(6, "王五五", "東莞", "冰箱", 30))

cv := NewCityVisitor()
orderService.Accept(cv)
cv.Report()

pv := NewProductVisitor()
orderService.Accept(pv)
pv.Report()
}


責任編輯:武曉燕 來源: 網管叨bi叨
相關推薦

2023-05-04 08:47:31

命令模式抽象接口

2023-05-15 08:51:46

解釋器模式定義

2023-05-26 08:41:23

模式Go設計模式

2023-03-21 07:57:37

Go語言設計模式

2023-03-27 00:20:48

2021-02-01 10:01:58

設計模式 Java單例模式

2023-03-06 08:46:12

2021-04-19 21:25:48

設計模式到元

2022-01-12 13:33:25

工廠模式設計

2023-11-02 21:11:11

JavaScript設計模式

2020-08-21 07:23:50

工廠模式設計

2020-11-04 08:54:54

狀態模式

2013-11-26 16:09:34

Android設計模式

2020-11-03 13:05:18

命令模式

2020-10-23 09:40:26

設計模式

2022-09-21 08:47:05

項目多線程對象

2021-11-28 22:33:01

Go選項模式

2022-12-26 08:54:02

Go設計模式接口,

2012-07-10 02:01:53

設計模式命令模式

2021-09-29 13:53:17

抽象工廠模式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99re6在线视频精品免费 | 国产精品国色综合久久 | 亚洲二区视频 | 99久久亚洲 | 国产精品不卡视频 | 亚洲草草视频 | 欧美午夜一区 | 亚洲二区在线观看 | 国产精品一区二区三区四区五区 | 免费在线成人 | 精品国产免费一区二区三区五区 | 久久久久久久国产精品 | 欧美一区在线看 | 中文字幕二区三区 | 久久在视频 | 午夜三区| 免费在线精品视频 | 免费视频一区二区 | 99av成人精品国语自产拍 | 一区二区三区日 | 91超碰在线| 不卡一区二区三区四区 | 精品av | 亚洲精品美女视频 | 高清国产一区二区 | 亚洲一区自拍 | 国产精品69毛片高清亚洲 | 日韩一区不卡 | 毛片免费观看 | 91av在线视频观看 | 欧美一区二区 | 免费在线一区二区 | 最新国产精品视频 | 91在线精品视频 | 国产欧美日韩精品一区二区三区 | 国产麻豆乱码精品一区二区三区 | 欧美高清一级片 | 日韩aⅴ在线观看 | 日韩精品久久久久 | 男女视频在线看 | 午夜视频网|