Rust领域驱动设计宏库domain-macros的使用,简化领域模型代码生成与DDD模式实现

Rust领域驱动设计宏库domain-macros的使用,简化领域模型代码生成与DDD模式实现

domain-macros是一个Rust宏库,旨在简化领域驱动设计(DDD)模式的实现,通过自动生成领域模型代码来提高开发效率。

安装

在项目目录中运行以下Cargo命令:

cargo add domain-macros

或者在Cargo.toml中添加:

domain-macros = "0.11.0"

基本使用示例

以下是一个使用domain-macros实现简单领域模型的完整示例:

use domain_macros::{entity, value_object};

// 定义一个值对象
#[value_object]
pub struct Email(String);

impl Email {
    pub fn new(email: String) -> Result<Self, String> {
        if email.contains('@') {
            Ok(Email(email))
        } else {
            Err("Invalid email format".to_string())
        }
    }
}

// 定义一个实体
#[entity]
pub struct User {
    id: u64,
    email: Email,
    name: String,
}

impl User {
    pub fn new(id: u64, email: Email, name: String) -> Self {
        User { id, email, name }
    }
}

// 使用示例
fn main() {
    let email = Email::new("test@example.com".to_string()).unwrap();
    let user = User::new(1, email, "John Doe".to_string());
    
    println!("User ID: {}", user.id());
    println!("User Email: {}", user.email().0);
    println!("User Name: {}", user.name());
}

主要特性

  1. #[entity]宏自动为结构体生成:

    • getter方法
    • 标识符比较功能
    • 基本领域对象特征实现
  2. #[value_object]宏提供:

    • 值对象语义
    • 不可变性保证
    • 值相等性比较
  3. 其他领域模式支持:

    • 聚合根
    • 领域事件
    • 仓储模式

完整示例demo

以下是一个更完整的领域模型示例,展示聚合根和值对象的使用:

use domain_macros::{entity, value_object, aggregate_root};
use uuid::Uuid;

// 值对象 - 地址
#[value_object]
pub struct Address {
    street: String,
    city: String,
    zip_code: String,
}

impl Address {
    pub fn new(street: String, city: String, zip_code: String) -> Self {
        Address { street, city, zip_code }
    }
}

// 实体 - 订单项
#[entity]
pub struct OrderItem {
    id: Uuid,
    product_id: Uuid,
    quantity: u32,
    unit_price: f64,
}

impl OrderItem {
    pub fn new(product_id: Uuid, quantity: u32, unit_price: f64) -> Self {
        OrderItem {
            id: Uuid::new_v4(),
            product_id,
            quantity,
            unit_price,
        }
    }
    
    pub fn total_price(&self) -> f64 {
        self.quantity as f64 * self.unit_price
    }
}

// 聚合根 - 订单
#[aggregate_root]
pub struct Order {
    id: Uuid,
    customer_id: Uuid,
    items: Vec<OrderItem>,
    shipping_address: Address,
    status: String,
}

impl Order {
    pub fn new(customer_id: Uuid, shipping_address: Address) -> Self {
        Order {
            id: Uuid::new_v4(),
            customer_id,
            items: Vec::new(),
            shipping_address,
            status: "Created".to_string(),
        }
    }
    
    pub fn add_item(&mut self, product_id: Uuid, quantity: u32, unit_price: f64) {
        self.items.push(OrderItem::new(product_id, quantity, unit_price));
    }
    
    pub fn total_amount(&self) -> f64 {
        self.items.iter().map(|item| item.total_price()).sum()
    }
    
    pub fn ship(&mut self) {
        self.status = "Shipped".to_string();
    }
}

// 使用示例
fn main() {
    let address = Address::new(
        "123 Main St".to_string(),
        "New York".to_string(),
        "10001".to_string()
    );
    
    let mut order = Order::new(Uuid::new_v4(), address);
    
    order.add_item(Uuid::new_v4(), 2, 19.99);
    order.add_item(Uuid::new_v4(), 1, 9.99);
    
    println!("Order ID: {}", order.id());
    println!("Total Amount: ${:.2}", order.total_amount());
    
    order.ship();
    println!("Order Status: {}", order.status());
}

许可证

BSD-3-Clause许可证


1 回复

Rust领域驱动设计宏库domain-macros使用指南

domain-macros是一个用于简化Rust中领域驱动设计(DDD)模式实现的宏库,它可以帮助开发者快速生成领域模型代码,减少样板代码编写。

主要功能

  1. 自动生成领域模型的基本结构
  2. 简化值对象(Value Object)的实现
  3. 提供聚合根(Aggregate Root)的支持
  4. 生成领域事件(Domain Event)相关代码

安装

在Cargo.toml中添加依赖:

[dependencies]
domain-macros = "0.1"  # 请使用最新版本

基本用法

1. 定义实体(Entity)

use domain_macros::{entity, AggregateRoot};

#[entity]
#[derive(AggregateRoot)]
struct User {
    id: UserId,
    name: String,
    email: Email,
}

这会自动生成:

  • new()方法
  • getter/setter方法
  • 基本的领域验证逻辑

2. 定义值对象(Value Object)

use domain_macros::value_object;

#[value_object]
#[derive(Debug, Clone, PartialEq)]
struct Email(String);

这会自动实现:

  • 值对象的基本特征
  • 输入验证
  • 转换方法

3. 定义聚合根(Aggregate Root)

use domain_macros::{AggregateRoot, entity};

#[entity]
#[derive(AggregateRoot)]
struct Order {
    id: OrderId,
    items: Vec<OrderItem>,
    status: OrderStatus,
}

impl Order {
    pub fn add_item(&mut self, item: OrderItem) {
        // 业务逻辑
        self.items.push(item);
        // 自动记录领域事件
        self.record(OrderItemAdded::new(item));
    }
}

4. 定义领域事件(Domain Event)

use domain_macros::domain_event;
use serde::{Serialize, Deserialize};

#[domain_event]
#[derive(Serialize, Deserialize)]
struct OrderCreated {
    order_id: OrderId,
    created_at: DateTime<Utc>,
    user_id: UserId,
}

高级用法

自定义验证逻辑

use domain_macros::value_object;

#[value_object]
struct Password(String);

impl Password {
    fn validate(&self) -> Result<(), String> {
        if self.0.len() < 8 {
            return Err("Password must be at least 8 characters".into());
        }
        Ok(())
    }
}

使用领域事件

use domain_macros::{AggregateRoot, entity};

#[entity]
#[derive(AggregateRoot)]
struct Product {
    id: ProductId,
    name: String,
    price: Money,
    // ...
}

impl Product {
    pub fn change_price(&mut self, new_price: Money) {
        self.price = new_price;
        self.record(ProductPriceChanged {
            product_id: self.id,
            new_price,
        });
    }
}

完整示例

use domain_macros::{entity, value_object, AggregateRoot, domain_event};
use uuid::Uuid;

// 定义ID类型
#[value_object]
struct UserId(Uuid);

// 定义值对象
#[value_object]
struct Email(String);

impl Email {
    fn validate(&self) -> Result<(), String> {
        if !self.0.contains('@') {
            return Err("Invalid email format".into());
        }
        Ok(())
    }
}

// 定义领域事件
#[domain_event]
struct UserRegistered {
    user_id: UserId,
    email: Email,
    registered_at: chrono::DateTime<chrono::Utc>,
}

// 定义聚合根
#[entity]
#[derive(AggregateRoot)]
struct User {
    id: UserId,
    name: String,
    email: Email,
    is_active: bool,
}

impl User {
    pub fn register(name: String, email: Email) -> Result<Self, String> {
        email.validate()?;
        
        let user = Self {
            id: UserId(Uuid::new_v4()),
            name,
            email,
            is_active: true,
        };
        
        user.record(UserRegistered {
            user_id: user.id,
            email: user.email.clone(),
            registered_at: chrono::Utc::now(),
        });
        
        Ok(user)
    }
}

注意事项

  1. 宏生成的代码可能会影响编译时间
  2. 需要熟悉DDD基本概念才能有效使用
  3. 某些高级定制可能需要手动实现部分逻辑

domain-macros库通过减少样板代码让开发者能更专注于领域逻辑的实现,是Rust中进行DDD开发的实用工具。

回到顶部