Skip to main content

Module observer

Module observer 

Source
Expand description

Observer + Event Subscriber — 模型生命周期观察者模式

对应文档 6.8 节改进项 32(Observer)+ 33(Event Subscriber)。

§核心概念

  • Observer:观察者接口,订阅模型生命周期事件(INSERT/UPDATE/DELETE/FIND)
  • EventSubscriber:事件订阅者,按事件类型订阅(比 Observer 更细粒度)
  • EventDispatcher:事件分发器,管理 Observer 与 EventSubscriber 的注册和分发

§与 Behaviors 的区别

特性Behaviors (behaviors.rs)Observer (本模块)
注册方式Model 内部声明外部注册到 Dispatcher
解耦程度Model 与 Behavior 强耦合完全解耦,Model 无需感知
适用场景字段自动填充(时间戳/操作人)审计日志、缓存失效、外部通知
事件粒度4 个生命周期事件可订阅特定事件类型

§设计灵感

  • Doctrine EventSubscriber / LifecycleCallback
  • Hibernate EntityListener / @PostPersist
  • Laravel Eloquent Observer
  • Rails ActiveRecord Callbacks + Observers

§使用示例

use sz_orm_core::observer::{
    Event, EventDispatcher, EventSubscriber, Observer, SubscriberResult,
};
use sz_orm_core::hooks::HookContext;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use sz_orm_core::Value;

// 1. 审计日志订阅者(订阅所有事件)
struct AuditLogSubscriber {
    logs: Arc<Mutex<Vec<String>>>,
}

impl EventSubscriber for AuditLogSubscriber {
    fn subscribed_events(&self) -> Vec<Event> {
        vec![Event::AfterInsert, Event::AfterUpdate, Event::AfterDelete]
    }

    fn on_event(&self, event: Event, ctx: &HookContext, attrs: &HashMap<String, Value>) -> SubscriberResult<()> {
        let mut logs = self.logs.lock().unwrap();
        logs.push(format!("{:?} on attrs with {} fields", event, attrs.len()));
        Ok(())
    }
}

// 2. 缓存失效订阅者(仅订阅写入事件)
struct CacheInvalidationSubscriber;

impl EventSubscriber for CacheInvalidationSubscriber {
    fn subscribed_events(&self) -> Vec<Event> {
        vec![Event::AfterUpdate, Event::AfterDelete]
    }

    fn on_event(&self, event: Event, _ctx: &HookContext, attrs: &HashMap<String, Value>) -> SubscriberResult<()> {
        // 失效缓存逻辑...
        let _ = (event, attrs);
        Ok(())
    }
}

// 3. 注册并触发事件
let logs = Arc::new(Mutex::new(Vec::new()));
let mut dispatcher = EventDispatcher::new();
dispatcher.subscribe(Box::new(AuditLogSubscriber { logs: logs.clone() }));
dispatcher.subscribe(Box::new(CacheInvalidationSubscriber));

let ctx = HookContext::default();
let attrs = HashMap::new();
dispatcher.dispatch(Event::AfterInsert, &ctx, &attrs);

assert_eq!(logs.lock().unwrap().len(), 1);

Structs§

AuditLogSubscriber
审计日志订阅者
EventDispatcher
事件分发器

Enums§

Event
模型生命周期事件类型
SubscriberError
订阅者错误类型

Traits§

EventSubscriber
事件订阅者 trait
Observer
模型观察者 trait

Type Aliases§

SubscriberResult
订阅者结果类型