Help us improve
Share bugs, ideas, or general feedback.
From grimoire
Models complex business software around the domain using ubiquitous language, bounded contexts, aggregates, and entities/value objects to reduce miscommunication between technical and business teams.
npx claudepluginhub jeffreytse/grimoire --plugin grimoireHow this skill is triggered — by the user, by Claude, or both
Slash command
/grimoire:apply-domain-driven-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Model software around the business domain using a shared language between developers and domain experts, and enforce architectural boundaries that isolate domain logic from infrastructure.
Models software around business domains using bounded contexts, aggregates, and ubiquitous language. Guides splitting monoliths into services and aligning code with business processes.
Apply DDD principles to model business domains, design aggregates, and establish clear language across teams. Use when modeling complex business logic or integrating domain experts.
Guides Domain-Driven Design for complex business logic: aggregates, bounded contexts, ubiquitous language, value objects, entities, and TypeScript implementations with invariants.
Share bugs, ideas, or general feedback.
Model software around the business domain using a shared language between developers and domain experts, and enforce architectural boundaries that isolate domain logic from infrastructure.
Adopted by: Amazon (domain-centric microservices), Vaughn Vernon's consulting clients across finance and healthcare, Thoughtworks architecture practice, Microsoft (used in Azure DevOps migration) Impact: Evans cites: teams using DDD reduce the time spent on bug-fixing due to domain misunderstanding by 40-60%; domain models that match business vocabulary reduce requirements translation errors; bounded contexts enable teams to scale without coordination overhead Why best: Most software failures are domain logic failures, not technology failures; DDD forces rigorous domain modeling that prevents logic from scattering across the codebase
Sources: Evans "Domain-Driven Design" Addison-Wesley (2003); Vernon "Implementing Domain-Driven Design" Addison-Wesley (2013); Fowler "Domain Driven Design" martinfowler.com
Build a ubiquitous language — Work with domain experts to establish a shared vocabulary. Every term used in conversation must be used exactly in the code (class names, method names, variable names). Divergence between the language experts use and the code is a bug waiting to happen. Document the glossary and enforce it in code review.
Identify bounded contexts — A bounded context is a boundary within which a ubiquitous language applies consistently. "Order" in the sales context (customer-facing) and "Order" in the fulfillment context (warehouse) are different models; force one model to represent both creates a sprawling, inconsistent mess. Name and map your bounded contexts explicitly.
Model the domain with aggregates — An aggregate is a cluster of domain objects treated as a single unit for data changes. Define aggregate roots (the entry point). Enforce: all modifications go through the root, external references hold only the root's ID, and invariants are maintained within the aggregate boundary. Aggregates are the transaction boundary.
Define entities vs. value objects — Entity: has identity that persists through state changes (Customer with customerId). Value object: defined by its attributes, no identity, immutable (Money with amount and currency). Make value objects immutable. Prefer value objects wherever identity is not required; they simplify reasoning and testing.
Implement repositories for persistence — A repository provides a collection-like interface for accessing aggregates. The domain model must not know about databases. Repository interfaces are defined in the domain layer; implementations live in the infrastructure layer. This keeps domain logic pure and independently testable.
Use domain services for business logic without a natural home — Logic that doesn't belong to a single aggregate (e.g., TransferService that moves money between two accounts) lives in a domain service. Domain services operate on domain objects, not DTOs or database records. Keep domain services thin; push logic into aggregates.
Apply domain events to communicate across contexts — When something significant happens in one bounded context that other contexts need to know about (OrderPlaced, PaymentConfirmed), publish a domain event. Context B subscribes to Context A's events; they never call Context A's internals directly. Events are the anti-corruption layer.
Map context relationships explicitly — Identify how bounded contexts relate: customer-supplier (one team is upstream/downstream), conformist (downstream accepts upstream model), anti-corruption layer (downstream translates upstream model), partnership (teams coordinate changes). The context map is an architectural diagram that drives team communication patterns.
Protect the domain from infrastructure — Apply Hexagonal Architecture (Ports and Adapters): the domain is the center; it defines interfaces (ports); infrastructure (HTTP, database, messaging) implements them (adapters). The domain has zero imports from frameworks or infrastructure. This is the architectural enforcement of DDD's separation of concerns.
Evolve the model iteratively — The domain model is not designed once; it's discovered through ongoing collaboration with domain experts. Schedule model review sessions when new requirements reveal gaps in the current model. Refactor the model (and the code) when the ubiquitous language evolves. A model that doesn't evolve becomes a legacy constraint.
Account and the expert says Portfolio, one of them is wrong and it must be resolved.