m09-domain

安装量: 572
排名: #1936

安装

npx skills add https://github.com/zhanghandong/rust-skills --skill m09-domain

Domain Modeling

Layer 2: Design Choices

Core Question

What is this concept's role in the domain?

Before modeling in code, understand:

Is it an Entity (identity matters) or Value Object (interchangeable)? What invariants must be maintained? Where are the aggregate boundaries? Domain Concept → Rust Pattern Domain Concept Rust Pattern Ownership Implication Entity struct + Id Owned, unique identity Value Object struct + Clone/Copy Shareable, immutable Aggregate Root struct owns children Clear ownership tree Repository trait Abstracts persistence Domain Event enum Captures state changes Service impl block / free fn Stateless operations Thinking Prompt

Before creating a domain type:

What's the concept's identity?

Needs unique identity → Entity (Id field) Interchangeable by value → Value Object (Clone/Copy)

What invariants must hold?

Always valid → private fields + validated constructor Transition rules → type state pattern

Who owns this data?

Single owner (parent) → owned field Shared reference → Arc/Rc Weak reference → Weak Trace Up ↑

To domain constraints (Layer 3):

"How should I model a Transaction?" ↑ Ask: What domain rules govern transactions? ↑ Check: domain-fintech (audit, precision requirements) ↑ Check: Business stakeholders (what invariants?)

Design Question Trace To Ask Entity vs Value Object domain- What makes two instances "the same"? Aggregate boundaries domain- What must be consistent together? Validation rules domain-* What business rules apply? Trace Down ↓

To implementation (Layer 1):

"Model as Entity" ↓ m01-ownership: Owned, unique ↓ m05-type-driven: Newtype for Id

"Model as Value Object" ↓ m01-ownership: Clone/Copy OK ↓ m05-type-driven: Validate at construction

"Model as Aggregate" ↓ m01-ownership: Parent owns children ↓ m02-resource: Consider Rc for shared within aggregate

Quick Reference DDD Concept Rust Pattern Example Value Object Newtype struct Email(String); Entity Struct + ID struct User { id: UserId, ... } Aggregate Module boundary mod order { ... } Repository Trait trait UserRepo { fn find(...) } Domain Event Enum enum OrderEvent { Created, ... } Pattern Templates Value Object struct Email(String);

impl Email { pub fn new(s: &str) -> Result { validate_email(s)?; Ok(Self(s.to_string())) } }

Entity struct UserId(Uuid);

struct User { id: UserId, email: Email, // ... other fields }

impl PartialEq for User { fn eq(&self, other: &Self) -> bool { self.id == other.id // Identity equality } }

Aggregate mod order { pub struct Order { id: OrderId, items: Vec, // Owned children // ... }

impl Order {
    pub fn add_item(&mut self, item: OrderItem) {
        // Enforce aggregate invariants
    }
}

}

Common Mistakes Mistake Why Wrong Better Primitive obsession No type safety Newtype wrappers Public fields with invariants Invariants violated Private + accessor Leaked aggregate internals Broken encapsulation Methods on root String for semantic types No validation Validated newtype Related Skills When See Type-driven implementation m05-type-driven Ownership for aggregates m01-ownership Domain error handling m13-domain-error Specific domain rules domain-*

返回排行榜