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

相关推荐
芝士熊爱编程7 小时前
创建型模式-单例模式
java·单例模式·设计模式
microrain8 小时前
从硬编码到热插拔:SagooIoT插件架构如何打破物联网平台的扩展瓶颈
物联网·golang·开源·sagooiot
geovindu9 小时前
go:Backtracking Algorithm
开发语言·后端·算法·golang·回溯算法
qq_452396239 小时前
第六篇:《并发编程核心:Goroutine 与 Channel》
golang
咖啡八杯9 小时前
GoF设计模式——访问者模式
设计模式·访问者模式
llwszx10 小时前
【Java/Go后端手撸原生Agent(第五篇):多工具并行调用 + BashTool执行引擎 + Judge证据链升级】
java·后端·golang·状态机·pydantic·agnet·llm-as-judge
FfHUCisI10 小时前
Go语言程序结构 —— 变量、声明与零值机制
golang
超人不会飞_Jay11 小时前
Go课程2
开发语言·后端·golang
谢栋_11 小时前
设计模式从入门到精通之(七)责任链模式
java·设计模式·责任链模式
晴空了无痕1 天前
从 Go 基础到 K8s:一条可落地的 Go 服务端成长路线
开发语言·后端·golang·kubernetes