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

本文介绍了观察者模式的概念,包括Subject(抽象主题)、Observer(观察者)和ConcreteSubject(具体主题)的角色,以及如何通过类图和Java代码实现。详细展示了如何在代码中添加观察者并触发状态变化通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 代码

  • 代码
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")
}
  • 输出
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)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玄德公笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值