• 代码事件派发机制(观察者模式)


    事件派发机制主要用来解决:

       代码解耦和维护,一般在代码中会要管理一些闭包函数  然后在指定的业务中触发运行闭包函数逻辑
       用了事件派发机制  就可以先把要处理的事件 挂在在一个事件管理类中  上面挂满要处理的闭包函数
       然后通过dispatch 出发要执行的任务 也就是闭包
    
    • 1
    • 2
    • 3

    1. PHP中实现

    在 PHP 中,你可以使用事件派发机制来实现基于观察者模式的事件驱动开发。下面是一个简单的示例来展示如何实现事件派发机制:

    
    
    class EventDispatcher
    {
        private $listeners = [];
    
        public function addListener($eventName, $listener)
        {
            $this->listeners[$eventName][] = $listener;
        }
    
        public function dispatch($eventName, $data = null)
        {
            if (isset($this->listeners[$eventName])) {
                foreach ($this->listeners[$eventName] as $listener) {
                    call_user_func($listener, $data);
                }
            }
        }
    }
    
    // 示例使用
    $dispatcher = new EventDispatcher();
    
    // 添加事件监听器
    $dispatcher->addListener('user.registered', function ($data) {
        echo "用户注册成功:{$data}\n";
    });
    
    $dispatcher->addListener('user.loggedIn', function ($data) {
        echo "用户登录成功:{$data}\n";
    });
    
    // 模拟触发事件
    $dispatcher->dispatch('user.registered', 'user123');
    $dispatcher->dispatch('user.loggedIn', 'user456');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在上面的示例中,我们创建了一个名为 EventDispatcher 的事件调度器类。该类包括 addListener() 方法用于添加事件监听器,和 dispatch() 方法用于触发事件并通知相应的监听器。

    通过调用 addListener() 方法,我们可以为特定的事件名称注册一个或多个监听器。这些监听器是以匿名函数的方式定义的,用于处理事件被触发时的逻辑。

    在 dispatch() 方法中,我们检查指定事件名称的监听器列表是否存在,然后依次调用每个监听器函数,并将事件数据作为参数传递给它们。

    最后,在示例的最后部分,我们通过调用 dispatch() 方法模拟触发了两个事件,然后相应的监听器函数被调用并处理事件。

    运行以上代码,将会输出如下信息:

    用户注册成功:user123
    用户登录成功:user456
    这样就实现了一个简单的事件派发机制。在实际的应用中,你可以根据需要扩展和定制事件调度器,添加更多的事件和监听器,以实现更复杂的业务逻辑。

    2 go语言中实现

    在 Go 语言中,你可以使用通道(channel)和协程(goroutine)的特性来实现一个简单的事件派发机制。下面是一个示例代码:

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    type Event struct {
    	Name string
    	Data interface{}
    }
    
    type EventDispatcher struct {
    	listeners map[string][]chan interface{}
    }
    
    func NewEventDispatcher() *EventDispatcher {
    	return &EventDispatcher{
    		listeners: make(map[string][]chan interface{}),
    	}
    }
    
    func (ed *EventDispatcher) AddListener(eventName string, listener chan interface{}) {
    	if _, ok := ed.listeners[eventName]; !ok {
    		ed.listeners[eventName] = make([]chan interface{}, 0)
    	}
    	ed.listeners[eventName] = append(ed.listeners[eventName], listener)
    }
    
    func (ed *EventDispatcher) Dispatch(eventName string, data interface{}) {
    	if listeners, ok := ed.listeners[eventName]; ok {
    		event := Event{
    			Name: eventName,
    			Data: data,
    		}
    		for _, listener := range listeners {
    			go func(ch chan interface{}) {
    				ch <- event
    			}(listener)
    		}
    	}
    }
    
    func main() {
    	dispatcher := NewEventDispatcher()
    
    	// 添加事件监听器
    	listener1 := make(chan interface{})
    	dispatcher.AddListener("event1", listener1)
    
    	listener2 := make(chan interface{})
    	dispatcher.AddListener("event2", listener2)
    
    	// 模拟触发事件
    	dispatcher.Dispatch("event1", "data1")
    	dispatcher.Dispatch("event2", "data2")
    
    	// 读取监听器收到的事件
    	go func(ch chan interface{}) {
    		for {
    			event := <-ch
    			fmt.Println(event)
    		}
    	}(listener1)
    
    	go func(ch chan interface{}) {
    		for {
    			event := <-ch
    			fmt.Println(event)
    		}
    	}(listener2)
    
    	// 等待事件处理
    	time.Sleep(time.Second)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    在上述示例中,我们定义了 Event 结构体来表示事件,其中包含事件名称和事件数据。EventDispatcher 结构体用于管理事件监听器和事件派发。通过 AddListener 方法可以为指定事件名称注册一个事件监听器,而 Dispatch 方法用于派发事件并通知相应的监听器。

    在 main 函数中,我们实例化了一个 EventDispatcher 对象,并添加了两个事件监听器,分别监听名为 “event1” 和 “event2” 的事件。

    然后,我们使用 Dispatch 方法模拟触发了 “event1” 和 “event2” 事件,并将相关数据传递给监听器。

    最后,我们在两个协程中创建了监听器函数,用于处理收到的事件。通过使用通道读取操作 <-ch,监听器函数可以不断等待事件的到来。

    运行以上代码,将会得到类似如下的输出:

    {event1 data1}
    {event2 data2}
    这样就实现了一个简单的事件派发机制。你可以根据需要扩展该事件派发器,增加更多事件和监听器,以满足具体的业务需求。同时需要注意,对于涉及并发的操作,需要进行适当的同步和错误处理。

  • 相关阅读:
    喜报 | 英码科技顺利通过2023年度广东省工程技术研究中心认定
    qt6 多媒体开发代码分析(二、录音)
    Android学习之路(17) Android Adapter详解
    .NET(C#) 如何配置用户首选项及保存用户设置
    软件的开发步骤,需求分析,开发环境搭建,接口文档 ---苍穹外卖1
    期权开户流程、交易时间和规则详解清晰易懂
    网络安全系列-三十七: 针对PCAP数据包进行探索性分析示例
    传统算法与神经网络算法,神经网络算法应用领域
    651页23万字智慧教育大数据信息化顶层设计及智慧应用建设方案
    html 按钮点击倒计时,限制不可点击
  • 原文地址:https://blog.csdn.net/cangqiong_xiamen/article/details/133635167