近来打算学习一下各种设计模式,有助于自己在开发过程中将项目结构设计得优雅一点
监听模式的实现(本质上与发布订阅模式差不多)
都是需要在观察者和被观察者之间建立桥梁。
被观察者需要记录观察者的对象,当有发生变化时,广播到每个观察者对象中去,观察者需要暴露一个接口来执行发生变化时的操作。
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)
}