rust-patterns 0.1.0

A modern Rust design patterns library with type-safe, efficient implementations
Documentation

Rust Patterns

一个现代化的 Rust 设计模式库,提供类型安全、高效的设计模式实现。

Rust Crates.io Documentation License

特性

  • 🚀 类型安全 - 充分利用 Rust 的类型系统确保编译时安全
  • 🧵 线程安全 - 所有组件都设计为线程安全,支持并发使用
  • 📦 零成本抽象 - 使用宏和编译时注册实现零运行时开销
  • 🔧 模块化设计 - 每个模式都是独立的,可按需使用
  • 📚 完整文档 - 详细的 API 文档和使用示例

支持的设计模式

1. 构建器模式 (Builder Pattern)

提供 builder_helper! 宏,为构建器类型添加条件性设置值的方法。

2. 工厂模式 (Factory Pattern)

包含完整的工厂模式实现,支持编译时注册和运行时查找。

3. 观察者模式 (Observer Pattern)

类型安全的发布-订阅机制,支持弱引用和错误处理策略。

安装

将以下内容添加到你的 Cargo.toml 文件中:

[dependencies]

rust-patterns = "0.1"

快速开始

构建器模式

use rust_patterns::builder_helper;

struct User {
    name: String,
    email: Option<String>,
    age: Option<u32>,
}

struct UserBuilder {
    name: String,
    email: Option<String>,
    age: Option<u32>,
}

impl UserBuilder {
    fn new(name: String) -> Self {
        Self {
            name,
            email: None,
            age: None,
        }
    }

    fn email(mut self, email: String) -> Self {
        self.email = Some(email);
        self
    }

    fn age(mut self, age: u32) -> Self {
        self.age = Some(age);
        self
    }

    fn build(self) -> User {
        User {
            name: self.name,
            email: self.email,
            age: self.age,
        }
    }
}

// 为 UserBuilder 添加条件性设置方法
builder_helper!(Self, UserBuilder);

fn main() {
    let user = UserBuilder::new("Alice".to_string())
        .when_some(Some("alice@example.com".to_string()), |b, e| b.email(e))
        .when_some(None::<u32>, |b, a| b.age(a)) // 不会设置年龄
        .build();
    
    println!("User: {}, Email: {:?}", user.name, user.email);
}

工厂模式

use rust_patterns::{simple_factory, register_factory, FactoryFallback};

// 定义产品 trait
#[simple_factory]
pub trait Shape {
    fn draw(&self);
    fn area(&self) -> f64;
}

// 实现具体产品
#[derive(Default)]
struct Circle {
    radius: f64,
}

impl Shape for Circle {
    fn draw(&self) {
        println!("Drawing circle with radius {}", self.radius);
    }
    
    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
}

#[derive(Default)]
struct Square {
    side: f64,
}

impl Shape for Square {
    fn draw(&self) {
        println!("Drawing square with side {}", self.side);
    }
    
    fn area(&self) -> f64 {
        self.side * self.side
    }
}

// 注册工厂
register_factory!(dyn Shape, "circle", Circle);
register_factory!(dyn Shape, "square", Square);

fn main() {
    // 使用工厂创建实例
    match ShapeFactory::create("circle", FactoryFallback::First) {
        Ok((id, shape)) => {
            println!("Created shape: {}", id);
            shape.draw();
            println!("Area: {}", shape.area());
        }
        Err(e) => eprintln!("Error creating shape: {}", e),
    }
}

观察者模式

use std::sync::Arc;
use rust_patterns::{Observer, Subject, NotifyStrategy};

// 定义状态类型
#[derive(Debug, Clone)]
struct Temperature {
    celsius: f64,
}

// 实现观察者
struct TemperatureDisplay;

impl Observer for TemperatureDisplay {
    type State = Temperature;
    type Error = String;

    fn update(&self, state: &Temperature) -> Result<(), String> {
        println!("Temperature updated: {:.1}°C", state.celsius);
        Ok(())
    }
}

struct TemperatureLogger;

impl Observer for TemperatureLogger {
    type State = Temperature;
    type Error = String;

    fn update(&self, state: &Temperature) -> Result<(), String> {
        println!("[LOG] Temperature: {:.1}°C", state.celsius);
        Ok(())
    }
}

fn main() {
    // 创建主题
    let mut weather_station = Subject::<Temperature, String>::new();
    
    // 创建观察者
    let display = Arc::new(TemperatureDisplay);
    let logger = Arc::new(TemperatureLogger);
    
    // 附加观察者
    weather_station.attach(display.clone());
    weather_station.attach(logger.clone());
    
    // 通知观察者
    let temp = Temperature { celsius: 25.5 };
    match weather_station.notify(&temp, NotifyStrategy::StopOnError) {
        Ok(()) => println!("All observers notified successfully"),
        Err(e) => eprintln!("Error notifying observers: {}", e),
    }
    
    // 分离观察者
    weather_station.detach(logger);
    
    // 再次通知
    let temp2 = Temperature { celsius: 26.0 };
    weather_station.notify(&temp2, NotifyStrategy::IgnoreError).unwrap();
}

API 文档

构建器模式

builder_helper!

为构建器类型添加 when_some 方法,允许条件性地设置可选值。

builder_helper!(Self, BuilderType1, BuilderType2);
//builder_helper!(&mut Self, BuilderType1, BuilderType2);

生成的 when_some 方法签名:

fn when_some<T>(self, value: Option<T>, func: impl FnOnce(Self, T) -> Self) -> Self

工厂模式

#[simple_factory] 属性宏

应用于 trait 定义,自动生成对应的工厂结构体。

#[simple_factory]
pub trait MyTrait {
    // trait 方法
}

// 也可以指定额外的 trait bound
#[simple_factory(Send + Sync)]
pub trait MyTrait {
    // trait 方法
}

register_factory!

注册具体实现到工厂系统。

register_factory!(dyn MyTrait, "implementation_id", ConcreteType);

FactoryFallback 枚举

定义找不到指定工厂时的回退策略:

  • First - 使用第一个可用的工厂
  • Last - 使用最后一个可用的工厂
  • NoFallback - 不允许回退,返回错误

观察者模式

Observer trait

观察者必须实现的 trait:

pub trait Observer {
    type State;
    type Error;
    
    fn update(&self, state: &Self::State) -> Result<(), Self::Error>;
}

Subject 结构体

管理观察者列表的主题:

pub struct Subject<T, E> {
    // ...
}

impl<T, E> Subject<T, E> {
    pub fn new() -> Self;
    pub fn with_capacity(capacity: usize) -> Self;
    pub fn attach(&mut self, observer: Arc<dyn Observer<State = T, Error = E>>);
    pub fn detach(&mut self, observer: Arc<dyn Observer<State = T, Error = E>>);
    pub fn notify(&self, state: &T, error_strategy: NotifyStrategy) -> Result<(), E>;
}

NotifyStrategy 枚举

定义通知失败时的处理策略:

  • StopOnError - 立即停止并返回错误
  • IgnoreError - 忽略错误并继续通知

高级用法

自定义错误处理

use rust_patterns::{Observer, Subject, NotifyStrategy};
use thiserror::Error;

#[derive(Debug, Error)]
enum AppError {
    #[error("Invalid temperature: {0}")]
    InvalidTemperature(f64),
    #[error("Network error")]
    NetworkError,
}

struct TemperatureValidator;

impl Observer for TemperatureValidator {
    type State = f64;
    type Error = AppError;

    fn update(&self, state: &f64) -> Result<(), AppError> {
        if *state < -273.15 {
            Err(AppError::InvalidTemperature(*state))
        } else {
            println!("Valid temperature: {}", state);
            Ok(())
        }
    }
}

线程安全的观察者

use std::sync::Arc;
use std::thread;
use rust_patterns::{Observer, Subject, NotifyStrategy};

struct ConcurrentObserver {
    id: usize,
}

impl Observer for ConcurrentObserver {
    type State = String;
    type Error = ();

    fn update(&self, state: &String) -> Result<(), ()> {
        println!("Observer {} received: {}", self.id, state);
        Ok(())
    }
}

fn main() {
    let mut subject = Subject::<String, ()>::new();
    let mut handles = vec![];
    
    // 创建多个观察者
    for i in 0..5 {
        let observer = Arc::new(ConcurrentObserver { id: i });
        subject.attach(observer.clone());
        
        // 在单独的线程中模拟异步通知
        let subject_clone = subject.clone();
        let handle = thread::spawn(move || {
            let message = format!("Message from thread {}", i);
            subject_clone.notify(&message, NotifyStrategy::IgnoreError).unwrap();
        });
        handles.push(handle);
    }
    
    for handle in handles {
        handle.join().unwrap();
    }
}

性能特点

  • 零运行时开销:工厂模式使用编译时注册,无运行时查找开销
  • 内存高效:观察者模式使用弱引用,避免内存泄漏
  • 线程安全:所有组件都设计为 Send + Sync
  • 无动态分配:构建器模式在编译时生成代码

贡献指南

  1. Fork 项目
  2. 创建功能分支 (git checkout -b feature/amazing-feature)
  3. 提交更改 (git commit -m 'Add amazing feature')
  4. 推送到分支 (git push origin feature/amazing-feature)
  5. 打开 Pull Request

许可证

本项目基于 MIT 许可证 - 查看 LICENSE 文件了解详情。

致谢

  • 感谢 Rust 社区提供的优秀工具和库
  • 受《设计模式:可复用面向对象软件的基础》一书启发
  • 感谢所有贡献者和用户

联系方式

如有问题或建议,请通过以下方式联系:


Rust Patterns - 让 Rust 设计模式更简单、更安全、更高效! 🦀