《golang设计模式》第三部分·行为型模式-07-观察者模式(Observer)/发布者—订阅者模式

文章目录

  • [1. 概念](#1. 概念)
    • [1.1 角色](#1.1 角色)
    • [1.2 类图](#1.2 类图)
  • [2. 代码示例](#2. 代码示例)
    • [2.1 代码](#2.1 代码)
    • [2.2 类图](#2.2 类图)

1. 概念

观察者(Observer)指当目标对象状态发生变化后,对状态变化事件进行响应或处理的对象。

1.1 角色

  • Subject(抽象主题):
    • 它可以有多个观察者,并将所有观察者对象的引用保存在一个集合里
    • 被观察者提供一个接口,可以增加和删除观察者角色
  • ConcreteSubject(具体主题):
    • 将有关状态存入具体观察者对象
    • 在主题发生改变时,给所有的观察者发出通知
  • Observer(抽象观察者):
    • 为所有的具体观察者定义一个更新接口,在收到主题的通知时能够及时的更新自己
  • ConcreteObserver(具体观察者):
    • 实现抽象观察者角色定义的更新接口,以便使本身的状态与主题状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。

1.2 类图

Subject -observer:List +Add(o:Observer) +NotifyObserver() +ChangeState() ConcreteSubject +ChangeState() <<interface>> Observer +Update(s:State) ConcreteObserverA +Update(s:State) ConcreteObserverB +Update(s:State)

2. 代码示例

2.1 代码

  • 代码
go 复制代码
package main

import "fmt"

//定义抽象主题,它是观察者的聚合
type Subject struct{  
   observers []Observer
}

//定义一个方法,为抽象主题添加观察者
func (c *Subject) Attach(o ...Observer) {
   c.observers = append(c.observers, o...)
}


//定义实际主题,继承抽象主题,它是实际的被观察者。
type ConcreteSubject struct {
   Subject    Subject
   context   string
  }

  
//依次通知观察者
func (c *ConcreteSubject) notify() {
   for _, o := range c.Subject.observers {
    o.Update(c)
   }
 }
 
//具体抽象主题的,同时发送通知给观察者
func (c *ConcreteSubject) UpdateContext(context string) {
   c.context = context
   c.notify()
}
  
//定义抽象观察者
type Observer interface {
   Update(*ConcreteSubject)
}
  
//定义具体观察者
type ConcreteObserverA struct {
   name string
}

//更新观察者
func (r *ConcreteObserverA) Update(c *ConcreteSubject) {
   fmt.Printf("%s receive %q\n", r.name, c.context)
} 
  
//定义具体观察者
type ConcreteObserverB struct {
   name string
}

//更新观察者
func (r *ConcreteObserverB) Update(c *ConcreteSubject) {
   fmt.Printf("%s receive %q\n", r.name, c.context)
} 

//定义具体观察者
type ConcreteObserverC struct {
   name string
}

//更新观察者
func (r *ConcreteObserverC) Update(c *ConcreteSubject) {
   fmt.Printf("%s receive %q\n", r.name, c.context)
} 

func main() {
   //实例化抽象主题
   subject := Subject{
      observers: make([]Observer, 0),
   }
 
   //实例化3观察者
   concreteObserverA := &ConcreteObserverA{
      name: "concreteObserverA",
     }
     concreteObserverB := &ConcreteObserverB{
      name: "concreteObserverB",
     }
     concreteObserverC := &ConcreteObserverC{
      name: "concreteObserverC",
     }
   //将3个观察者加入抽象主题
   subject.Attach(concreteObserverA,concreteObserverB,concreteObserverC)

   //实例化具体主题
   concreteSubject := &ConcreteSubject{
      Subject: subject,
   }

   //更新具体主题,它将通知所有观察者
   concreteSubject.UpdateContext("updata context")
}
  • 输出
shell 复制代码
concreteObserverA receive "updata context"
concreteObserverB receive "updata context"
concreteObserverC receive "updata context"

2.2 类图

Subject +[]Observe observers +Attach(o ...Observer) ConcreteSubject +Subject:Subject +context:String +Notify() +UpdateContext(context string) <<interface>> Observer +Update(c *ConcreteSubject) ConcreteObserverA +Name:String +Update(c *ConcreteSubject) ConcreteObserverB +Name:String +Update(c *ConcreteSubject) ConcreteObserverC +Name:String +Update(c *ConcreteSubject)

相关推荐
刘铸纬6 小时前
Golang中defer和return顺序
开发语言·后端·golang
明戈戈6 小时前
设计模式-模板方法模式
设计模式·模板方法模式
python资深爱好者6 小时前
在什么情况下你会使用设计模式
设计模式
PingCAP10 小时前
Dify + TiDB Vector,快速构建你的AI Agent
数据库·人工智能·设计模式
BoldExplorer11 小时前
设计模式(四)责任链模式
设计模式·责任链模式
GIS_JH12 小时前
设计模式简单示例
设计模式
搬砖的小熊猫13 小时前
设计模式探索:策略模式
设计模式·策略模式
liupenglove13 小时前
golang线程池ants-实现架构
开发语言·后端·golang·多线程
桦说编程16 小时前
深入理解 Future, CompletableFuture, ListenableFuture,回调机制
java·后端·设计模式
spell00718 小时前
设计模式之代理模式
设计模式·代理模式