go笔记:事件机制与观察者模式

  • 2019 年 11 月 22 日
  • 笔记

模拟C#的eventHandler。乖乖就是真开心的意思。。。

示例:猫和老鼠(猫捉老鼠,系统触发警告事件通知老鼠快跑)

package main    import (      . "eventHandler"      "fmt"  )    func main() {      handler := NewEventHander()      defer handler.Release()        yzh := NewMouse("yzh")      zhh := NewMouse("zhh")        handler.AddListener("yzh", yzh.Shout)      handler.AddListener("zhh", zhh.Shout)        Alert()        args := NewEventArgs()      args.Param["info"] = "快跑!"        handler.OnEvent(args)        fmt.Println("yzh总被大猫吃掉")      Alert()      handler.RemoveListener("yzh")      handler.OnEvent(args)  }    func Alert() {      fmt.Println("大猫出来了!!")  }    func NewMouse(name string) *Mouse {      fmt.Println("小老鼠", name, "出来了。")      return &Mouse{name}  }    type Mouse struct {      Name string  }    func (mouse *Mouse) Shout(args *EventArgs) {      if v, ok := args.Param["info"]; ok {          fmt.Println(mouse.Name, v.(string))      }  }

eventHandler库:

package eventHandler    import (      "fmt"  )    func NewEventHander() *EventHandler {      return &EventHandler{make(map[string]chan *EventArgs)}  }    func NewEventArgs() *EventArgs {      return &EventArgs{make(map[string]interface{})}  }    type EventHandler struct {      listeners map[string]chan *EventArgs  }    type EventArgs struct {      Param map[string]interface{}  }    func (handler *EventHandler) AddListener(callbackName string, callback func(*EventArgs)) {      if _, ok := handler.listeners[callbackName]; !ok {          ch := make(chan *EventArgs)            handler.listeners[callbackName] = ch          go func() {              for {                  event := <-ch                  if event == nil {                      break                  }                  (callback)(event)              }          }()      }  }    func (handler *EventHandler) RemoveListener(callbackName string) (listenersLength int) {      if _, ok := handler.listeners[callbackName]; ok {          handler.listeners[callbackName] <- nil          delete(handler.listeners, callbackName)      }      return len(handler.listeners)  }    func (handler *EventHandler) OnEvent(event *EventArgs) {      for _, v := range handler.listeners {          v <- event      }  }    func (handler *EventHandler) Release() {      for _, v := range handler.listeners {          v <- nil      }  }