yonatankarp/software-design-skills

ddd-domain-service

Use when behavior doesn't naturally belong to a single entity or value object — phrases like "domain service", "this logic spans multiple aggregates", "where does this go", "the entity is starting to know too much", "we need a calculator/coordinator that is…

查看源码

使用方法

  1. 复制安装命令,在自己的智能体环境安装前先检查源码包。
  2. 从原始文档核对所需工具、凭据和支持的宿主。
  3. 说明输入材料与期望交付物,并对照来源检查输出。
npx skills add https://github.com/yonatankarp/software-design-skills --skill ddd-domain-service

开始前需了解

  • 安装不包含模型订阅、API 额度或访问文件的权限。
  • 仓库星数和安装量反映活跃情况,不等于独立质量或安全测试。
仓库原始内容

按源仓库内容呈现,保留标题、案例、代码、表格、链接以及原文引用的演示图片。

One-line summary

A domain service is a stateless operation in the domain layer that doesn't naturally sit on a single entity or value object — usually because it coordinates multiple aggregates or involves a domain computation that isn't anchored to one thing.

When to use this skill

  • A cohesive domain operation involves multiple aggregates (e.g., transferring money between two Account aggregates).
  • A calculation involves domain types but isn't naturally a method on any of them (e.g., currency conversion, given exchange rates).
  • Forcing the behavior onto one of the participating entities would make that entity "know too much" about the others.

When NOT to use this skill

  • The logic fits cleanly on a single entity — put it there.
  • The work is application-layer orchestration (handling a use case, opening a transaction, calling repositories) — that is an application service, not a domain service.
  • The work is infrastructure (HTTP calls, database access, message sending) — that is an infrastructure service.

Core content

Three kinds of services often coexist in a DDD codebase. Keep them distinct:

Domain service. Lives in the domain layer. Operates on domain types only. Stateless. Expresses a verb in the ubiquitous language — TransferService.transfer(fromAccount, toAccount, amount), not AccountUtils.handleTransfer(...).

Application service. Orchestrates a use case. Opens transactions, calls repositories, invokes domain services, dispatches events. Stateless. Lives in the application layer.

Infrastructure service. Talks to the outside world — sends HTTP, writes to a database, publishes to a queue. Lives in the infrastructure layer.

A domain service is named for what it does in domain terms. TransferService and ExchangeRateConverter are good names. TransferManager and TransferHelper are smells — they hide the verb behind technical noise.

Decision heuristics

  • Prefer entity behavior. Reach for a domain service only when the operation involves multiple aggregates or has no natural home.
  • If a domain service has state, it is almost certainly misclassified — make it a domain entity, a value object, or move the state into one of the participating aggregates.
  • If a domain service grows to dozens of methods, it is probably a "transaction script" in disguise — split it or push behavior back onto entities.

Anti-patterns

  • *Service suffix on every class — the domain becomes a collection of transaction scripts over data DTOs (see anemic-domain-model in ddd-anti-patterns).
  • Putting infrastructure (database, HTTP) inside a domain service — couples the domain to deployment concerns.
  • Domain services that mutate the entities they are given without going through the entity's methods — bypasses invariants.
  • Stateful "services" that hold caches, sessions, or other process state.

See also

  • ddd-entity — first preference is to put behavior here.
  • ddd-aggregate — domain services often coordinate across aggregates.
  • ddd-anti-patterns — anemic-model and service-explosion smells.

References

  • Evans, Domain-Driven Design (2003), Ch. 5 (A Model Expressed in Software).

按任务相关推荐

来自同一仓库

更多 Skills

全部 Skills
yonatankarp
社区

arch-adr

Use when recording an architectural decision so future maintainers know why — phrases like "ADR", "architecture decision record", "why did we pick X", "lightweight architecture documentation", "decision log", "should this be an ADR", "tribal knowledge", "we chose this two years ago and now nobody remembers why". Defines the ADR as a short, structured document capturing what was decided, why, alternatives considered, and consequences — written at the time of the decision and kept in the repo.

安装量
2
GitHub Stars
1
最近更新
5月19日
yonatankarp
社区

arch-fitness-functions

Use when enforcing architectural characteristics through automation — phrases like "architecture fitness function", "evolutionary architecture", "architecture tests", "ArchUnit", "dependency rules in CI", "automated architecture checks", "guardrails", "drift detection". Defines fitness functions as automated checks that verify architectural characteristics on every change, catching drift before it accumulates.

安装量
2
GitHub Stars
1
最近更新
5月19日
yonatankarp
社区

arch-microservices

Use when designing or reviewing a microservices architecture — phrases like "microservices", "should we split this service", "service boundaries", "bounded context per service", "API gateway", "backend for frontend", "BFF", "service mesh", "microservices vs monolith", "database per service", "data ownership". Defines microservices as independently deployable services aligned with business capabilities — and the discipline of resisting the style until the monolith proves inadequate.

安装量
2
GitHub Stars
1
最近更新
5月19日
yonatankarp
社区

arch-strangler-fig

Use when migrating a legacy system incrementally — phrases like "strangler fig", "strangler pattern", "incremental migration", "monolith to microservices", "rewrite without big bang", "replace legacy in place", "facade in front of the legacy system", "anticorruption layer". Defines Fowler's Strangler Fig as the migration discipline of gradually replacing legacy functionality behind a stable facade, never doing a big-bang rewrite.

安装量
2
GitHub Stars
1
最近更新
5月19日