0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是觀察者設(shè)計(jì)模式?Golang中的觀察者模式介紹

馬哥Linux運(yùn)維 ? 來(lái)源:稀土掘金 ? 2024-01-08 10:08 ? 次閱讀

當(dāng)涉及到訂單處理系統(tǒng)時(shí),觀察者設(shè)計(jì)模式可以用于實(shí)現(xiàn)訂單狀態(tài)的變化和通知。在這篇文章中,我們將介紹如何使用Golang來(lái)實(shí)現(xiàn)觀察者設(shè)計(jì)模式,并提供一個(gè)基于訂單處理系統(tǒng)的代碼示例。

什么是觀察者設(shè)計(jì)模式?

觀察者設(shè)計(jì)模式是一種行為型設(shè)計(jì)模式,它允許對(duì)象之間的松耦合通信。在這種模式中,一個(gè)對(duì)象(稱為主題Subject)維護(hù)一組依賴于它的對(duì)象(稱為觀察者Observer)的列表,并在狀態(tài)改變時(shí)自動(dòng)通知它們。觀察者模式可以用于實(shí)現(xiàn)事件驅(qū)動(dòng)的系統(tǒng),其中對(duì)象之間的交互是通過(guò)事件的發(fā)布和訂閱來(lái)完成的。

應(yīng)用場(chǎng)景:訂單處理系統(tǒng)

在訂單處理系統(tǒng)中,訂單的狀態(tài)可能會(huì)發(fā)生變化,例如創(chuàng)建、支付、發(fā)貨、取消等。當(dāng)訂單狀態(tài)發(fā)生變化時(shí),我們希望通知相關(guān)的觀察者進(jìn)行相應(yīng)的處理,例如更新庫(kù)存、發(fā)送通知等。

實(shí)現(xiàn)觀察者設(shè)計(jì)模式

在Golang中,可以使用channel和goroutine來(lái)實(shí)現(xiàn)觀察者設(shè)計(jì)模式。

首先,我們定義一個(gè)訂單結(jié)構(gòu)體,包含訂單的基本信息和狀態(tài):


type Order struct {
  ID     string
  Status string
}

然后,我們定義一個(gè)觀察者接口,包含一個(gè)Update方法,用于處理訂單狀態(tài)變化的通知:

type Observer interface {
  Update(order *Order, wg *sync.WaitGroup)
}

接下來(lái),我們定義一個(gè)主題結(jié)構(gòu)體,使用channel和goroutine來(lái)通知觀察者:

type Subject struct {
  observers []Observer
}


func (s *Subject) Register(observer Observer) {
  s.observers = append(s.observers, observer)
}


func (s *Subject) Notify(order *Order) {
  wg := sync.WaitGroup{}
  wg.Add(len(s.observers))


  errCh := make(chan error, len(s.observers))


  for _, observer := range s.observers {
    go func(obs Observer) {
      defer wg.Done()


      err := obs.Update(order, &wg)
      if err != nil {
        errCh <- err
      }
    }(observer)
  }


  wg.Wait()
  close(errCh)


  // 處理異常
  for err := range errCh {
    fmt.Println("Error occurred:", err)
  }
}




我們首先創(chuàng)建了一個(gè)errCh(類型為chan error)來(lái)接收觀察者處理過(guò)程中可能發(fā)生的異常。然后,在每個(gè)觀察者的goroutine中,我們通過(guò)閉包的方式傳遞observer并在處理完成后檢查是否有異常發(fā)生。如果有異常,我們將其發(fā)送到errCh中。

在Notify方法的最后,我們關(guān)閉了errCh通道,并通過(guò)range循環(huán)來(lái)處理所有的異常。

接下來(lái),我們實(shí)現(xiàn)兩個(gè)觀察者:庫(kù)存觀察者和通知觀察者。

庫(kù)存觀察者用于更新庫(kù)存狀態(tài):


type InventoryObserver struct{}


func (io *InventoryObserver) Update(order *Order, wg *sync.WaitGroup) {
  defer wg.Done()


  // 更新庫(kù)存狀態(tài)
  fmt.Printf("Inventory Observer: Order %s status changed to %s
", order.ID, order.Status)
}




通知觀察者用于發(fā)送通知:


type NotificationObserver struct{}


func (no *NotificationObserver) Update(order *Order, wg *sync.WaitGroup) {
  defer wg.Done()


  // 發(fā)送通知
  fmt.Printf("Notification Observer: Order %s status changed to %s
", order.ID, order.Status)
}




最后,我們?cè)谥骱瘮?shù)中使用觀察者模式來(lái)處理訂單狀態(tài)變化的通知:


func main() {
  order := &Order{
    ID:     "123",
    Status: "Created",
  }


  subject := &Subject{}
  subject.Register(&InventoryObserver{})
  subject.Register(&NotificationObserver{})


  // 模擬訂單狀態(tài)變化
  order.Status = "Paid"
  subject.Notify(order)


  order.Status = "Shipped"
  subject.Notify(order)
}


我們創(chuàng)建了一個(gè)訂單對(duì)象和一個(gè)主題對(duì)象,并注冊(cè)了庫(kù)存觀察者。然后,我們模擬訂單狀態(tài)的變化,通過(guò)調(diào)用Notify方法并發(fā)地通知觀察者進(jìn)行處理。

通過(guò)使用channel和goroutine,我們可以實(shí)現(xiàn)觀察者模式的并發(fā)處理,提高系統(tǒng)的性能和響應(yīng)能力。

使用觀察者設(shè)計(jì)模式的一些優(yōu)點(diǎn)

松耦合:觀察者模式可以將觀察者和主題(或被觀察者)對(duì)象解耦。觀察者只需要關(guān)注主題的狀態(tài)變化,而不需要了解具體的實(shí)現(xiàn)細(xì)節(jié)。這樣可以使得系統(tǒng)更加靈活和可擴(kuò)展。

可重用性:通過(guò)將觀察者和主題對(duì)象分離,可以使得它們可以在不同的上下文中重復(fù)使用。例如,可以在不同的業(yè)務(wù)場(chǎng)景中使用相同的觀察者來(lái)處理不同的主題對(duì)象。

易于擴(kuò)展:當(dāng)需要添加新的觀察者或主題時(shí),觀察者模式可以很方便地進(jìn)行擴(kuò)展。只需要實(shí)現(xiàn)新的觀察者或主題對(duì)象,并注冊(cè)到主題對(duì)象中即可。

事件驅(qū)動(dòng):觀察者模式適用于事件驅(qū)動(dòng)的系統(tǒng)。當(dāng)主題對(duì)象的狀態(tài)發(fā)生變化時(shí),可以通過(guò)觸發(fā)事件來(lái)通知所有的觀察者進(jìn)行相應(yīng)的處理。

如果不使用觀察者設(shè)計(jì)模式

訂單業(yè)務(wù)可能會(huì)以一種更加緊耦合的方式實(shí)現(xiàn)。以下是一個(gè)示例代碼,展示了在沒(méi)有使用觀察者模式的情況下,如何處理訂單狀態(tài)變化的問(wèn)題:


type Order struct {
  ID     string
  Status string
}


type OrderProcessor struct {
  inventoryObserver    *InventoryObserver
  notificationObserver *NotificationObserver
}


func NewOrderProcessor() *OrderProcessor {
  return &OrderProcessor{
    inventoryObserver:    &InventoryObserver{},
    notificationObserver: &NotificationObserver{},
  }
}


func (op *OrderProcessor) Process(order *Order) {
  // 更新庫(kù)存
  op.inventoryObserver.Update(order)


  // 發(fā)送通知
  op.notificationObserver.Update(order)
}


func main() {
  order := &Order{
    ID:     "123",
    Status: "Created",
  }


  op := NewOrderProcessor()


  // 模擬訂單狀態(tài)變化
  order.Status = "Paid"
  op.Process(order)


  order.Status = "Shipped"
  op.Process(order)
}


在這個(gè)示例中,OrderProcessor對(duì)象負(fù)責(zé)處理訂單狀態(tài)變化。它內(nèi)部包含了InventoryObserver和NotificationObserver對(duì)象,并在Process方法中依次調(diào)用它們的Update方法來(lái)處理訂單狀態(tài)變化。

這種實(shí)現(xiàn)方式存在一些問(wèn)題:

緊耦合:OrderProcessor對(duì)象直接依賴于InventoryObserver和NotificationObserver對(duì)象。如果需要添加或刪除其他觀察者,需要修改OrderProcessor的代碼,導(dǎo)致代碼的可維護(hù)性和可擴(kuò)展性下降。

代碼重復(fù):每當(dāng)有新的觀察者需要處理訂單狀態(tài)變化時(shí),都需要在OrderProcessor中添加相應(yīng)的代碼。這樣會(huì)導(dǎo)致代碼的重復(fù)和冗余。

可擴(kuò)展性差:在沒(méi)有使用觀察者模式的情況下,很難在系統(tǒng)中添加新的觀察者,因?yàn)槊看味夹枰薷腛rderProcessor的代碼。







審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 處理系統(tǒng)
    +關(guān)注

    關(guān)注

    0

    文章

    93

    瀏覽量

    16651

原文標(biāo)題:Golang中的觀察者模式:優(yōu)化訂單處理系統(tǒng)

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    UVM設(shè)計(jì)模式觀察者模式解讀

    Observer Pattern:對(duì)象之間定義一個(gè)一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象改變的時(shí)候,所有依賴對(duì)象都會(huì)自動(dòng)收到通知。
    的頭像 發(fā)表于 08-24 17:39 ?1002次閱讀
    UVM設(shè)計(jì)<b class='flag-5'>模式</b>之<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>解讀

    如何觀察重復(fù)的公告?

    我能夠建立和運(yùn)行“第10天”觀察員樣本項(xiàng)目。我在另一個(gè)DeV板上運(yùn)行了一個(gè)信標(biāo),當(dāng)我啟動(dòng)觀察者時(shí),它報(bào)告了“不可連接的單向廣告”,但是沒(méi)有新的事件,盡管我知道信標(biāo)必須定期發(fā)布一個(gè)廣告。作為證據(jù),如果
    發(fā)表于 10-14 07:06

    CC2540廣播角色和觀察者角色切換代碼怎么編寫(xiě)?

    希望一個(gè)CC2540先通過(guò)觀察者角色獲取其他廣播的廣播數(shù)據(jù),然后在切換為廣播角色將這些數(shù)據(jù)廣播給另外一個(gè)觀察者?這樣就需要編程實(shí)現(xiàn)觀察者
    發(fā)表于 03-16 10:27

    RN4020觀察者模式無(wú)法正常工作怎么回事

    中心,支持MLDP,并使UART流控制R,1//重新引導(dǎo),使更改生效J,1//觀察者模式你對(duì)這個(gè)問(wèn)題有什么想法?謝謝,弗朗西斯科
    發(fā)表于 04-22 09:03

    屬性觀察者的特點(diǎn)

    屬性觀察者,類似于觸發(fā)器。用來(lái)監(jiān)視屬性的除初始化之外的屬性值變化,當(dāng)屬性值發(fā)生改變時(shí)可以對(duì)此作出響應(yīng)。有如下特點(diǎn): 1,不僅可以在屬性值改變后觸發(fā)didSet,也可以在屬性值改變前觸發(fā)willSet
    發(fā)表于 11-04 07:10

    觀察者模式在嵌入式編程設(shè)計(jì)中有何作用

    觀察者模式是最常見(jiàn)的模式之一。這種模式提供一種方法來(lái)時(shí)對(duì)象“監(jiān)聽(tīng)”其他對(duì)象,而不需要修改任何數(shù)據(jù)服務(wù)器。在嵌入式領(lǐng)域,這意味著數(shù)據(jù)能夠很容易分享給其他元素。
    發(fā)表于 12-22 08:31

    基于觀察者模式的屏幕布局控件設(shè)計(jì)

    觀察者模式作為設(shè)計(jì)模式中行為模式的一種,解決了上述具有一對(duì)多依賴關(guān)系對(duì)象重用問(wèn)題。文中在分析觀察者模式
    發(fā)表于 02-13 16:20 ?4次下載
    基于<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>的屏幕布局控件設(shè)計(jì)

    Java設(shè)計(jì)模式分析之觀察者

    觀察者模式的流程跟報(bào)紙訂閱方式一致,即:觀察者模式=出版+訂閱,只是名稱不一樣,出版
    發(fā)表于 09-26 17:36 ?0次下載

    在 Java8 環(huán)境下實(shí)現(xiàn)觀察者模式的實(shí)例分析

    的一個(gè)組成部分。目前雖然已經(jīng)有大量關(guān)于觀察者模式的文章,但它們都專注于在 Java 的實(shí)現(xiàn),卻忽視了開(kāi)發(fā)在Java中使用觀察者
    發(fā)表于 10-12 16:09 ?0次下載
    在 Java8 環(huán)境下實(shí)現(xiàn)<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>的實(shí)例分析

    大陸正在研發(fā)一款路況觀察者應(yīng)用

    據(jù)外媒報(bào)道,大陸正在研發(fā)一款路況觀察者(Road Condition Observer)應(yīng)用。隨著傳感器及攝像頭技術(shù)的愈發(fā)成熟,再結(jié)合車載流媒體數(shù)據(jù),或許能夠完成該應(yīng)用的設(shè)計(jì)。此外,工程師還將為該應(yīng)用寫(xiě)入成熟的算法。
    發(fā)表于 05-15 11:30 ?993次閱讀

    GoF設(shè)計(jì)模式觀察者模式

    現(xiàn)在有 2 個(gè)服務(wù),Service A 和 Service B,通過(guò) REST 接口通信;Service A 在某個(gè)業(yè)務(wù)場(chǎng)景下調(diào)用 Service B 的接口完成一個(gè)計(jì)算密集型任務(wù),假設(shè)接口為 http://service_b/api/v1/domain;該任務(wù)運(yùn)行時(shí)間很長(zhǎng),但 Service A 不想一直阻塞在接口調(diào)用上。為了滿足 Service A 的要求,通常有 2 種方案:
    的頭像 發(fā)表于 07-25 11:32 ?989次閱讀

    設(shè)計(jì)模式行為型:觀察者模式

    定義對(duì)象之間的一種一對(duì)多依賴關(guān)系,使得每一個(gè)對(duì)象發(fā)生狀態(tài)的變化時(shí),其相關(guān)依賴對(duì)象皆得到通知并被自動(dòng)更新,又稱為發(fā)布-訂閱模式、模型-視圖模式、源-監(jiān)聽(tīng)器模式或從屬
    的頭像 發(fā)表于 06-07 16:56 ?636次閱讀
    設(shè)計(jì)<b class='flag-5'>模式</b>行為型:<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>

    觀察者模式,超詳細(xì)!

    觀察者模式建議你為發(fā)布類添加訂閱機(jī)制, 讓每個(gè)對(duì)象都能訂閱或取消訂閱發(fā)布事件流。 不要害怕! 這并不像聽(tīng)上去那么復(fù)雜。 實(shí)際上, 該機(jī)制包括 1) 一個(gè)用于存儲(chǔ)訂閱
    的頭像 發(fā)表于 08-21 16:06 ?1111次閱讀
    <b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>,超詳細(xì)!

    基于觀察者模式設(shè)計(jì)的框架-REB,使代碼模塊化

    設(shè)計(jì)模式里面的觀察者模式,一直是作者想去設(shè)計(jì)一套框架來(lái)闡述這一個(gè)模式,因此REB(Rice Event Broker)就是為了完成觀察者
    的頭像 發(fā)表于 10-17 09:35 ?620次閱讀
    基于<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>設(shè)計(jì)的框架-REB,使代碼模塊化

    一文解析BLE觀察者模式回調(diào)機(jī)制

    nRF5 SDK從版本14開(kāi)始,對(duì)事件回調(diào)機(jī)制做了更新,引入了觀察者模式,以解耦不同BLE Layer對(duì)BLE事件的回調(diào)函數(shù)。
    的頭像 發(fā)表于 11-27 10:07 ?904次閱讀
    一文解析BLE<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>回調(diào)機(jī)制