ESLint InterlaceESLint Interlace
Plugin: modularityRules

ddd-anemic-domain-model

ESLint rule documentation for ddd-anemic-domain-model

📡 Live from GitHub — This documentation is fetched directly from ddd-anemic-domain-model.md and cached for 6 hours.

Keywords: ddd-anemic-domain-model, domain-driven design, rich domain model, anemic domain model, anti-pattern, encapsulation, business logic, Aggregate Root, ESLint rule

Detects entities with only getters/setters and no business logic, enforcing the Rich Domain Model over the Anemic Domain Model anti-pattern.

Detects entities with only getters/setters and no business logic. This rule is part of eslint-plugin-modularity and helps enforce strong Domain-Driven Design (DDD) principles by encouraging behavior-rich entities.

Quick Summary

AspectDetails
SeverityMedium (maintainability/design)
Auto-Fix❌ No
CategoryModularity
ESLint MCP✅ Optimized for ESLint MCP integration
Best ForDomain layers in DDD-based architectures
Suggestions✅ 3 suggestions for remediation

The Anti-Pattern: Anemic Domain Model

Vulnerability/Issue: An Anemic Domain Model describes a domain layer where objects contain data but little or no logic. Instead, the logic is found in "Service" objects that manipulate the domain objects' state via getters and setters.

Risk: Anemic models lead to "Transaction Scripts" where business logic is fragmented across services, making it difficult to maintain invariants, increasing code duplication, and violating basic object-oriented principles like encapsulation.

Error Message Format

The rule provides LLM-optimized error messages with actionable architectural guidance:

📐 ARCHITECTURE | Anemic domain model detected in {{className}} | MEDIUM
   Fix: Add business logic methods to create a rich domain model | https://martinfowler.com/bliki/AnemicDomainModel.html

Message Components

ComponentPurposeExample
Domain StandardDesign benchmarkDDD Aggregate
Issue DescriptionSpecific violationClass User has no business logic (only getters/setters)
Severity & ImpactDesign assessmentMEDIUM
Fix InstructionActionable remediationAdd domain behavior methods to encapsulate state
Technical TruthOfficial referenceAnemic Domain Model

Rule Details

This rule identifies classes that don't satisfy the minimum requirement of business logic methods. It ignores standard Data Transfer Objects (DTOs) by default using configurable naming patterns.

Why This Matters

IssueImpactSolution
💊 EncapsulationState can be corrupted from anywhereMove logic into the entity and make setters private/protected
🧩 DuplicationLogic repeated in multiple servicesConsolidate logic as methods on the domain model
🛠️ MaintainabilityHard to find where behavior residesBehavior lives with the data it operates on

Configuration

OptionTypeDefaultDescription
minBusinessMethodsnumber1Minimum methods required to not be considered anemic
ignoreDtosbooleantrueWhether to ignore classes matching DTO patterns
dtoPatternsstring[]['DTO', 'Dto', 'Data', 'Request', 'Response', 'Payload']Naming patterns used to identify DTOs/Data objects

Examples

❌ Incorrect

// Anemic Domain Model (Logic-less Entity)
class BankAccount {
  private balance: number = 0;

  public getBalance(): number {
    return this.balance;
  }

  public setBalance(amount: number): void {
    this.balance = amount;
  }
}

// Logic is forced into an external service
class BankService {
  withdraw(account: BankAccount, amount: number) {
    if (account.getBalance() >= amount) {
      account.setBalance(account.getBalance() - amount);
    }
  }
}

✅ Correct

// Rich Domain Model (Encapsulated Behavior)
class BankAccount {
  private balance: number = 0;

  public withdraw(amount: number): void {
    if (amount <= 0) throw new Error('Amount must be positive');
    if (this.balance < amount) throw new Error('Insufficient funds');

    this.balance -= amount;
  }

  public getBalance(): number {
    return this.balance;
  }
}

Configuration Examples

Enforce Stricter Models

{
  rules: {
    'modularity/ddd-anemic-domain-model': ['error', {
      minBusinessMethods: 2,
      dtoPatterns: ['Model', 'Entity'] // Also ignore these patterns
    }]
  }
}

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Complex Setter Logic

Why: If a setter contains complex validation, the rule might still consider it a "simple setter" depending on the implementation complexity.

Mitigation: Review setters for business rule enforcement.

Dynamic Methods

Why: Methods added to the prototype dynamically or via decorators that aren't statically visible might result in false positives.

Mitigation: Use the minBusinessMethods: 0 if your framework uses heavy metaprogramming.

References

On this page

No Headings