代码解耦和维护,一般在代码中会要管理一些闭包函数 然后在指定的业务中触发运行闭包函数逻辑
用了事件派发机制 就可以先把要处理的事件 挂在在一个事件管理类中 上面挂满要处理的闭包函数
然后通过dispatch 出发要执行的任务 也就是闭包
在 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');
在上面的示例中,我们创建了一个名为 EventDispatcher 的事件调度器类。该类包括 addListener() 方法用于添加事件监听器,和 dispatch() 方法用于触发事件并通知相应的监听器。
通过调用 addListener() 方法,我们可以为特定的事件名称注册一个或多个监听器。这些监听器是以匿名函数的方式定义的,用于处理事件被触发时的逻辑。
在 dispatch() 方法中,我们检查指定事件名称的监听器列表是否存在,然后依次调用每个监听器函数,并将事件数据作为参数传递给它们。
最后,在示例的最后部分,我们通过调用 dispatch() 方法模拟触发了两个事件,然后相应的监听器函数被调用并处理事件。
运行以上代码,将会输出如下信息:
用户注册成功:user123
用户登录成功:user456
这样就实现了一个简单的事件派发机制。在实际的应用中,你可以根据需要扩展和定制事件调度器,添加更多的事件和监听器,以实现更复杂的业务逻辑。
在 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)
}
在上述示例中,我们定义了 Event 结构体来表示事件,其中包含事件名称和事件数据。EventDispatcher 结构体用于管理事件监听器和事件派发。通过 AddListener 方法可以为指定事件名称注册一个事件监听器,而 Dispatch 方法用于派发事件并通知相应的监听器。
在 main 函数中,我们实例化了一个 EventDispatcher 对象,并添加了两个事件监听器,分别监听名为 “event1” 和 “event2” 的事件。
然后,我们使用 Dispatch 方法模拟触发了 “event1” 和 “event2” 事件,并将相关数据传递给监听器。
最后,我们在两个协程中创建了监听器函数,用于处理收到的事件。通过使用通道读取操作 <-ch,监听器函数可以不断等待事件的到来。
运行以上代码,将会得到类似如下的输出:
{event1 data1}
{event2 data2}
这样就实现了一个简单的事件派发机制。你可以根据需要扩展该事件派发器,增加更多事件和监听器,以满足具体的业务需求。同时需要注意,对于涉及并发的操作,需要进行适当的同步和错误处理。