使用Go实现监听模式

近来打算学习一下各种设计模式,有助于自己在开发过程中将项目结构设计得优雅一点

监听模式的实现(本质上与发布订阅模式差不多)

都是需要在观察者和被观察者之间建立桥梁。

被观察者需要记录观察者的对象,当有发生变化时,广播到每个观察者对象中去,观察者需要暴露一个接口来执行发生变化时的操作。

package main

import "fmt"

// obvsersable 被观察者接口应该实现的基本方法
type obvsersable interface {
	addObsver(obsver)
	removeObsver(obsver)
	notify(obvsersable)
}

// 观察者 通过update方法去接收被观察者的变化
type obsver interface {
	update(obvsersable)
}

// WaterHeater 相当于被观察者,实现被观察者接口
type WaterHeater struct {
	obsvers     []obsver
	temperature int
}

func (o *WaterHeater) addObsver(ob obsver) {
	// 这里需要加锁,由于是示例就略过了
	o.obsvers = append(o.obsvers, ob)
}

// notify 广播给观察者发生了变化
func (o *WaterHeater) notify(ob obvsersable) {
	for _, i := range o.obsvers {
		i.update(ob)
	}
}

func (o *WaterHeater) removeObsver(ob obsver) {
	// 这里需要加锁,由于是示例就略过了
	for index, value := range o.obsvers {
		if value == ob {
			o.obsvers = append(o.obsvers[:index], o.obsvers[index+1:]...) //  从切片中删除元素
			break
		}
	}
}

func (o *WaterHeater) getTemperature() int {
	return o.temperature
}

func (o *WaterHeater) setTemperature(tem int) {
	o.temperature = tem
	o.notify(o)
}

// WashingMode 相当于观察者
type WashingMode struct {
	limitTem int
}

func (o *WashingMode) update(ob obvsersable) {
	waterheater := ob.(*WaterHeater) // 断言获取结构体类型
	tem := waterheater.getTemperature()
	if tem > o.limitTem {
		fmt.Println("可以洗澡了")
	} else {
		fmt.Println("不可以洗澡")
	}
}

func main() {
	wash1 := &WashingMode{limitTem: 50}
	wash2 := &WashingMode{limitTem: 40}
	waterheater := &WaterHeater{}
	waterheater.addObsver(wash1)
	waterheater.addObsver(wash2)
	waterheater.setTemperature(12)
	waterheater.setTemperature(41)
	waterheater.setTemperature(56)
	waterheater.removeObsver(wash2)
	waterheater.setTemperature(12)
	waterheater.setTemperature(41)
	waterheater.setTemperature(56)
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以回答这个问题。在Go语言中,可以使用channel来实现监听模式。首先定义一个事件结构体,包含事件名称和事件数据。然后定义一个事件监听器类型,包含一个channel和一个事件处理函数。当事件发生时,可以通过channel将事件发送给所有监听器,监听器收到事件后调用事件处理函数进行处理。以下是一个简单的示例代码: ```go type Event struct { Name string Data interface{} } type Listener struct { ch chan Event handler func(Event) } func (l *Listener) Listen() { for { event := <-l.ch l.handler(event) } } func NewListener(handler func(Event)) *Listener { return &Listener{ ch: make(chan Event), handler: handler, } } type Emitter struct { listeners []*Listener } func (e *Emitter) AddListener(handler func(Event)) { listener := NewListener(handler) e.listeners = append(e.listeners, listener) go listener.Listen() } func (e *Emitter) Emit(event Event) { for _, listener := range e.listeners { listener.ch <- event } } ``` 使用示例: ```go func main() { emitter := &Emitter{} listener1 := func(event Event) { fmt.Printf("Listener1 received event %s: %v\n", event.Name, event.Data) } listener2 := func(event Event) { fmt.Printf("Listener2 received event %s: %v\n", event.Name, event.Data) } emitter.AddListener(listener1) emitter.AddListener(listener2) emitter.Emit(Event{Name: "test", Data: "hello world"}) } ``` 输出: ``` Listener1 received event test: hello world Listener2 received event test: hello world ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值