Skip to main content

ObserverRegistry

Struct ObserverRegistry 

Source
pub struct ObserverRegistry<T: Observable> { /* private fields */ }
Expand description

观察者注册表

管理一组观察者并在状态变化时通知它们。注册表维护观察者的弱引用列表, 避免强引用循环导致的内存泄漏。

§类型参数

  • T: 被观察者类型,必须实现 Observable trait

§设计特点

  • 弱引用管理: 使用 Weak 引用存储观察者,允许观察者在不再需要时被释放
  • 自动清理: 在通知时自动跳过已释放的观察者弱引用
  • 通知策略: 支持两种通知策略
  • 防止重复: 检查观察者是否已存在,防止重复添加

§示例

use std::sync::Arc;
use rust_patterns_components::{Observable, Observer, ObserverRegistry};

struct Sensor;

impl Observable for Sensor {
    type State = String;
    type Error = String;

    fn attach(&mut self, _observer: Arc<dyn Observer<Subject = Self>>) {}
    fn detach(&mut self, _observer: Arc<dyn Observer<Subject = Self>>) {}
}

let mut registry = ObserverRegistry::<Sensor>::default();
// 使用 registry.attach() 添加观察者
// 使用 registry.notify() 通知观察者

Implementations§

Source§

impl<T> ObserverRegistry<T>
where T: Observable,

Source

pub fn new() -> Self

创建新的观察者注册表实例

§返回值

返回一个空的观察者注册表,不包含任何观察者。

Source

pub fn with_capacity(capacity: usize) -> Self

创建具有初始容量的观察者注册表实例

§参数
  • capacity: 初始容量,用于预分配内存
§返回值

返回一个具有指定初始容量的空注册表。

§性能

预分配容量可以避免后续添加观察者时的多次内存重新分配, 当已知观察者数量时建议使用此方法。

Source

pub fn attach(&mut self, observer: Arc<dyn Observer<Subject = T>>)

附加观察者

将观察者附加到注册表。方法内部会将观察者的强引用转换为弱引用, 并确保不会重复添加相同的观察者。

§参数
  • observer: 要附加的观察者强引用
§注意
  • 使用 Arc::downgrade 将强引用转换为弱引用,避免循环引用
  • 使用 Weak::ptr_eq 检查观察者是否已存在,防止重复添加
  • 观察者将在下次调用 notify 方法时收到状态更新通知
Source

pub fn detach(&mut self, observer: Arc<dyn Observer<Subject = T>>)

分离观察者

从注册表中分离指定的观察者。分离后,该观察者将不再收到状态更新通知。

§参数
  • observer: 要分离的观察者强引用
§注意
  • 使用 Arc::downgrade 将强引用转换为弱引用进行匹配
  • 使用 Weak::ptr_eq 进行引用相等性比较
  • 如果观察者不存在于列表中,此方法不会有任何效果
Source

pub fn notify( &self, state: &<T as Observable>::State, ) -> Result<(), <T as Observable>::Error>

通知所有观察者

向所有有效的观察者发送状态更新通知。

§参数
  • state: 要通知的新状态引用
§返回值
  • Ok(()): 所有观察者都成功处理了更新
  • Err(<T as Observable>::Error): 某个观察者处理更新时返回了错误,立即停止通知其他观察者
§行为
  • 遍历所有观察者并调用其 update 方法
  • 当某个观察者返回错误时,立即停止并返回该错误
  • 自动清理无效的观察者弱引用(通过 Weak::upgrade 过滤)
§性能

此方法会自动清理无效的观察者弱引用(通过 Weak::upgrade 过滤)。

Source

pub fn notify_ignore_error(&self, state: &<T as Observable>::State)

通知所有观察者状态变化,忽略错误

此方法会通知所有已注册的观察者状态变化,但会忽略任何观察者返回的错误。 即使某个观察者处理更新失败,也会继续通知其他观察者。

§参数
  • state - 要通知的状态变化
§行为
  • 遍历所有观察者并调用其 update 方法
  • 忽略所有观察者返回的错误(使用 let _ = ...
  • 自动清理无效的观察者弱引用(通过 Weak::upgrade 过滤)
§使用场景

适用于以下情况:

  • 观察者的错误不应该阻止其他观察者接收通知
  • 错误处理不是关键,可以安全忽略
  • 需要确保所有观察者都能收到通知,即使某些观察者可能失败
§notify 方法的区别
  • notify: 遇到第一个错误就停止,并返回该错误
  • notify_ignore_error: 忽略所有错误,继续通知所有观察者
§示例
use rust_pattern_components::{Observable, Observer, ObserverRegistry};
use std::sync::{Arc, Weak};

struct Counter {
    registry: ObserverRegistry<Self>,
    value: u64,
}

impl Observable for Counter {
    type State = u64;
    type Error = String;

    fn attach(&mut self, observer: Arc<dyn Observer<Subject = Self>>) {
        self.registry.attach(observer);
    }

    fn detach(&mut self, observer: Arc<dyn Observer<Subject = Self>>) {
        self.registry.detach(observer);
    }
}

let counter = Counter {
    registry: ObserverRegistry::new(),
    value: 42,
};

// 即使观察者可能失败,也会通知所有观察者
counter.registry.notify_ignore_error(&counter.value);

Trait Implementations§

Source§

impl<T> Default for ObserverRegistry<T>
where T: Observable,

Source§

fn default() -> Self

创建默认的观察者注册表实例

等同于调用 ObserverRegistry::new()

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.