目录
Define the Observer Interface
Define the Subject (Publisher)
Implement Concrete Observers
Usage Example
Key Points
首页 后端开发 Golang 您如何在Golang中实现观察者模式?

您如何在Golang中实现观察者模式?

Aug 14, 2025 pm 12:04 PM
golang 观察者模式

在Go中可以通过接口和通道实现观察者模式,定义Observer接口包含Update方法,Subject结构体维护观察者列表和消息通道,通过Attach添加观察者,Notify发送消息,listen goroutine异步广播更新,具体观察者如EmailService和LogService实现Update方法处理通知,主程序注册观察者并触发事件,实现松耦合的事件通知机制,适用于事件驱动系统、日志记录和消息通知等场景。

How do you implement an observer pattern in Golang?

In Go, you can implement the observer pattern using interfaces and channels to enable loose coupling between a subject (also called publisher) and its observers (subscribers). The idea is that when the subject's state changes, all registered observers are notified automatically.

Here’s how you can implement it cleanly in Go:


Define the Observer Interface

Start by defining an interface that all observers must satisfy:

type Observer interface {
    Update(message string)
}

Each observer will implement the Update method to react to changes.


Define the Subject (Publisher)

The subject maintains a list of observers and provides methods to add, remove, and notify them:

type Subject struct {
    observers []Observer
    messages  chan string
}

We use a channel (messages) to push updates asynchronously.

Initialize the subject:

func NewSubject() *Subject {
    subject := &Subject{
        observers: make([]Observer, 0),
        messages:  make(chan string, 10), // buffered channel
    }
    go subject.listen()
    return subject
}

The listen method runs in a goroutine and broadcasts messages to all observers:

func (s *Subject) listen() {
    for msg := range s.messages {
        for _, obs := range s.observers {
            obs.Update(msg)
        }
    }
}

Add methods to manage observers and trigger updates:

func (s *Subject) Attach(obs Observer) {
    s.observers = append(s.observers, obs)
}

func (s *Subject) Notify(msg string) {
    s.messages <- msg
}

Note: We don’t expose a Detach method here for simplicity, but you can add it by filtering the slice.


Implement Concrete Observers

Here’s a simple observer that prints the message:

type EmailService struct{}

func (e *EmailService) Update(message string) {
    fmt.Printf("Email sent with message: %s\n", message)
}

type LogService struct{}

func (l *LogService) Update(message string) {
    fmt.Printf("Log recorded: %s\n", message)
}

Usage Example

func main() {
    subject := NewSubject()

    emailService := &EmailService{}
    logService := &LogService{}

    subject.Attach(emailService)
    subject.Attach(logService)

    subject.Notify("User registered!")
    subject.Notify("Payment processed.")

    // Give time for messages to be processed
    time.Sleep(time.Millisecond * 100)
}

Output:

Email sent with message: User registered!
Log recorded: User registered!
Email sent with message: Payment processed.
Log recorded: Payment processed.

Key Points

  • Channels make the notification asynchronous and safe for concurrent use.
  • Interfaces allow flexibility — any type that implements Update can be an observer.
  • You can extend this with typed messages, error handling, or unsubscription logic.
  • For production use, consider using sync.RWMutex if observers are added/removed at runtime.

This pattern works well for event-driven systems, logging, notifications, or any scenario where components need to react to state changes without tight coupling. It’s simple, idiomatic Go, and avoids complex dependencies.

以上是您如何在Golang中实现观察者模式?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Stock Market GPT

Stock Market GPT

人工智能驱动投资研究,做出更明智的决策

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

描述观察者的设计模式及其在PHP中的实现。 描述观察者的设计模式及其在PHP中的实现。 Aug 15, 2025 pm 01:54 PM

TheObserverdesignpatternenablesautomaticnotificationofdependentobjectswhenasubject'sstatechanges.1)Itdefinesaone-to-manydependencybetweenobjects;2)Thesubjectmaintainsalistofobserversandnotifiesthemviaacommoninterface;3)Observersimplementanupdatemetho

如何将静态资产嵌入golang二进制 如何将静态资产嵌入golang二进制 Aug 30, 2025 am 04:50 AM

使用Go的embed包可以将静态资源直接嵌入二进制文件中。从Go1.16开始,通过在变量前使用//go:embed指令,可将单个文件、多个文件或整个目录嵌入,支持string、[]byte或embed.FS类型,嵌入内容在编译时固化到二进制中,路径需存在且区分大小写,推荐使用embed而非第三方工具如go-bindata,该方法简洁高效并已成为标准做法。

如何在Golang中构建一个无框架的静态API 如何在Golang中构建一个无框架的静态API Aug 20, 2025 am 01:47 AM

是的,使用Go标准库可以构建RESTfulAPI,通过net/http处理请求、encoding/json处理JSON数据、context管理上下文,结合http.ServeMux路由、手动路径解析、中间件封装和适当的错误处理,即可实现一个轻量、可控且无需外部框架的RESTful服务,最终以模块化结构提升可维护性,并完全掌握底层HTTP机制。

在Golang中格式化字符串的不同方法是什么? 在Golang中格式化字符串的不同方法是什么? Aug 23, 2025 pm 01:25 PM

fmt.Sprintf用于格式化并返回字符串,适合变量插入和存储;2.fmt.Fprintf将格式化结果直接写入io.Writer,适用于文件或网络写入;3.strings.Join用于高效连接字符串切片;4. 操作符适用于简单的一次性拼接;5.strings.Builder在循环或大量拼接时提供高性能;6.template包适用于基于数据的复杂动态文本生成,如HTML或配置文件。应根据性能、可读性和场景选择合适的方法,以完整句结束。

Golang Web服务器上下文中的中间件是什么? Golang Web服务器上下文中的中间件是什么? Sep 16, 2025 am 02:16 AM

MiddlewareinGowebserversarefunctionsthatinterceptHTTPrequestsbeforetheyreachthehandler,enablingreusablecross-cuttingfunctionality;theyworkbywrappinghandlerstoaddpre-andpost-processinglogicsuchaslogging,authentication,CORS,orerrorrecovery,andcanbechai

如何转换Golang的数据类型 如何转换Golang的数据类型 Aug 19, 2025 pm 02:43 PM

Go中的类型转换必须显式进行,不能隐式转换。对于数值类型,使用目标类型作为函数进行转换,如int64(a),但需注意溢出和精度丢失;字符串与数字之间的转换需使用strconv包中的Atoi、ParseInt、ParseFloat、Itoa和FormatFloat等函数,并处理可能的错误;字符串和字节切片可直接通过[]byte(s)和string(b)互相转换,适用于I/O和网络操作;interface{}(或any)类型的转换依赖类型断言x.(Type)或类型switch来安全提取原始类型,避免

如何与Golang的RabbitMQ这样的消息队列集成 如何与Golang的RabbitMQ这样的消息队列集成 Sep 02, 2025 am 07:46 AM

答案是通过使用amqp091-go库连接RabbitMQ、声明队列和交换机、安全发布消息、带QoS和手动确认的消息消费以及重连机制,可实现Go中可靠的消息队列集成,完整示例包含连接、生产、消费及错误处理流程,确保消息不丢失并支持断线重连,最终通过Docker运行RabbitMQ完成端到端集成。

Golang的表驱动测试是什么? Golang的表驱动测试是什么? Aug 28, 2025 am 01:38 AM

表格 - driventingingoisapatternthatuseadateTructure,通常是assliceofstructs,todefinemultipletestcaseswithInputswithInputsandsandsandsand and ExpectedOutputs,允许youtorunthesametestlogicacrogicacrogicacrogosallcasesinaloopsinaloop,whreducescodeDeDeDeDucodeDeDuplicationAndimProvesMaintibility; alectessesmainteraperience;

See all articles