Go 實現常用設計模式(五)觀察者模式

pibigstar發表於2019-09-07

意圖:
定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。
關鍵程式碼:
被觀察者持有了集合存放觀察者(收通知的為觀察者)
應用例項:

  1. 報紙訂閱,報社為被觀察者,訂閱的人為觀察者
  2. MVC模式,當model改變時,View檢視會自動改變,model為被觀察者,View為觀察者

Go實現觀察者模式

package observer

import "fmt"

// 報社 —— 客戶
type Customer interface {
    update()
}

type CustomerA struct {
}

func (*CustomerA) update() {
    fmt.Println("我是客戶A, 我收到報紙了")
}

type CustomerB struct {
}

func (*CustomerB) update() {
    fmt.Println("我是客戶B, 我收到報紙了")
}

// 報社 (被觀察者)
type NewsOffice struct {
    customers []Customer
}

func (n *NewsOffice) addCustomer(customer Customer) {
    n.customers = append(n.customers, customer)
}

func (n *NewsOffice) newspaperCome() {
    // 通知所有客戶
    n.notifyAllCustomer()
}

func (n *NewsOffice) notifyAllCustomer() {
    for _, customer := range n.customers {
        customer.update()
    }
}

測試用例

package observer

import "testing"

func TestObserver(t *testing.T) {

    customerA := &CustomerA{}
    customerB := &CustomerB{}

    office := &NewsOffice{}
    // 模擬客戶訂閱
    office.addCustomer(customerA)
    office.addCustomer(customerB)
    // 新的報紙
    office.newspaperCome()

}

具體程式碼

更詳細的程式碼可參考:https://github.com/pibigstar/go-demo 裡面包含了 Go 常用的設計模式、Go 面試易錯點、簡單的小專案(區塊鏈,爬蟲等)、還有各種第三方的對接(redis、sms、nsq、elsticsearch、alipay、oss...),如果對你有所幫助,請給個 Star,你的支援,是我最大的動力!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章