m09-domain

Layer 2: Design Choices

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "m09-domain" with this command: npx skills add rustfs/rustfs/rustfs-rustfs-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<Self, ValidationError> { 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<OrderItem>, // Owned children // ... }

impl Order {
    pub fn add_item(&#x26;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-*

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

m09-domain

No summary provided by upstream source.

Repository SourceNeeds Review
General

m09-domain

No summary provided by upstream source.

Repository SourceNeeds Review
General

coding-guidelines

No summary provided by upstream source.

Repository SourceNeeds Review