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());
}
主要特性
-
#[entity]
宏自动为结构体生成:- getter方法
- 标识符比较功能
- 基本领域对象特征实现
-
#[value_object]
宏提供:- 值对象语义
- 不可变性保证
- 值相等性比较
-
其他领域模式支持:
- 聚合根
- 领域事件
- 仓储模式
完整示例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)模式实现的宏库,它可以帮助开发者快速生成领域模型代码,减少样板代码编写。
主要功能
- 自动生成领域模型的基本结构
- 简化值对象(Value Object)的实现
- 提供聚合根(Aggregate Root)的支持
- 生成领域事件(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)
}
}
注意事项
- 宏生成的代码可能会影响编译时间
- 需要熟悉DDD基本概念才能有效使用
- 某些高级定制可能需要手动实现部分逻辑
domain-macros
库通过减少样板代码让开发者能更专注于领域逻辑的实现,是Rust中进行DDD开发的实用工具。