事件系统基本原理
事件系统可以将事件派发者与事件处理者解耦。例如,网络底层可以生成各种事件,在网络连接上后,网络底层只需将事件派发出去,而不需要关心到底哪些代码来响应连接上的逻辑。或者再比如,你注册、关注或者订阅某“大V”的社交消息后,“大V”发生的任何事件都会通知你,但他并不用了解粉丝们是如何为她喝彩或者疯狂的。
一个事件系统拥有如下特性:
- 能够实现事件的一方,可以根据事件 ID 或名字注册对应的事件。
- 事件发起者,会根据注册信息通知这些注册者。
- 一个事件可以有多个实现方响应。
package main
import "fmt"
var eventList = make(map[string][]func(interface{}), 10) // 所有事件的列表
type EventClass struct {
}
func eventClass() *EventClass { // 实例化对象
return &EventClass{}
}
func (e EventClass) registerEvent(name string, callback func(interface{})) {
oneEventList := eventList[name] // 获取总事件列表中某一个事件的列表
oneEventList = append(oneEventList, callback) // 某一个事件的列表添加新事件
eventList[name] = oneEventList // 把某一个事件列表放回到总事件列表中
}
func (e EventClass) callEvent(name string, param interface{}) {
oneEventList := eventList[name] // 根据名字获取一个事件列表
for _, event := range oneEventList { // 迭代事件列表,然后调用
event(param)
}
}
func networkRegister(i interface{}) {
user, ok := i.(string) // 取出接口中的数据
if ok {
fmt.Println("user: ", user)
}
}
func handleNetwork(i interface{}) {
par := i.(map[string]interface{}) // 取出接口中的数据
if id, ok := par["id"].([]int); ok {
fmt.Println("handle id: ", id)
}
if user, ok := par["user"].([]string); ok {
fmt.Println("handle user: ", user)
}
}
func main() {
eventObj := eventClass() // 调用实例化对象函数,并获取对象
eventObj.registerEvent("net_1", networkRegister) // 注册一个事件
eventObj.registerEvent("net_2", networkRegister) // 再次注册该事件
eventObj.registerEvent("net_3", handleNetwork) // 注册另一个处理事件
eventObj.callEvent("net_1", "zhong") // 调用事件
eventObj.callEvent("net_2", "xiaohang")
// 传递多种类型数据的参数
pa := make(map[string]interface{})
pa["id"] = []int{18, 22}
pa["user"] = []string{"zhong", "hang"}
eventObj.callEvent("net_3", pa)
}
// user: zhong
// user: xiaohang
// handle id: [18 22]
// handle user: [zhong hang]
一个完善的事件系统还会提供移除单个和所有事件的方法。