$30 off During Our Annual Pro Sale. View Details »

DDD Tactical modelling from Domain models to code

Avatar for Adelina Adelina
September 17, 2025

DDD Tactical modelling from Domain models to code

In this session, we’ll take a deep dive into Tactical Domain Driven Design and explore how to apply it in practice. Starting from a high-level architecture, we’ll zoom in on a specific Bounded Context to examine its tactical design in depth. We’ll identify candidates for key tactical patterns: aggregates, entities, value objects, services and policies.

Avatar for Adelina

Adelina

September 17, 2025
Tweet

More Decks by Adelina

Other Decks in Programming

Transcript

  1. OVERVIEW 2 • Foundation of tactical design • Structure complex

    domains into manageable, coherent parts • Align with business needs and technical implementation. Actionable insights • Tactical Modelling Terms • Entities • Aggregates • Identify services, events • Build diagrams • Skeleton Key Topics:
  2. Tactical Modelling Overview Tactical Modeling is applied within a Bounded

    Context 01 Tactical Modeling relies on Ubiquitous Language Aggregates – central tactical pattern 02 An Aggregate is composed of either a single Entity or a cluster of Entities and Value Objects 03 Entities/Aggregates must remain transactionally consistent throughout the Aggregate’s lifetime 04 An Aggregate is persisted and queried using its Repository 05
  3. Tactical Modeling Overview Domain Services - Business operations inside the

    Domain Model that don’t fit naturally as an operation on an Entity or a Value Object Domain Events - model significant occurrences in the domain Modules - logical grouping of objects (Java packages, C# namespaces)
  4. Entities We design a domain concept as an Entity when

    we care about its individuality, when distinguishing it from all other objects in a system is a mandatory constraint. An Entity is a unique thing and is capable of being changed continuously over a long period of time. The same object by identity.
  5. Unique Identity Distinct Identity – The core attributes that uniquely

    distinguish an entity and are often utilized to locate or associate it. Value Objects may contain the identity. • Immutable • Centralize the behavior related to the identity in one location
  6. Ways to discover Entities Starting from DB tables – wrong

    way, resulting in relational model in the code Start from the language (Ubiquitous Language)
  7. Ex: Discovering Entities in Customer context Consider the following use

    cases: Users of a system must be authenticated. Users possess personal information, including a name and contact information. User personal information may be changed by the users themselves or by a manager. User security credentials (passwords) may be changed. User can have different roles and permissions The user can be locked out if the password is wrong 3 times in a row
  8. Ubiquitous language terms - Customer Domain specific verbs: register, login,

    reset password, assign role, attribute, active, locked out. Domain concepts: Customer, Role, Password, Attribute, LoginResult. Domain behaviours: can login, is active, is deleted, cannot login until.
  9. Ex: Discovering Entities in IAM Context Identifying Entities: Customer –

    GUID (Globally Unique Identifier) - technical identity used to uniquely identify the entity across systems, databases and services. Username - a business identity — meaningful within the domain, but not guaranteed to be globally unique or immutable. Password – not part of identity, because it can be changed.
  10. Whole Object Validation If all properties are valid, that doesn’t

    mean that the whole object is valid. The object validity might depend on context Validation logic may be extracted into separate Strategy (GoF) or Specification (Evans) or implemented in the Aggregate’s Root command method that would validate the aggregated objects.
  11. Value Object Characteristics ❖ It measures, quantifies or describes a

    thing in the domain ❖ It can be maintained as immutable ❖ It models a conceptual whole by composing related attributes as an integral unit ❖ It is completely replaceable when the measurement or description changes ❖ It can be compared with others using Value equality ❖ Typical examples: Money, Email, Color, UniqueId
  12. Terms Aggregate A transactional graph of objects Aggregate Root The

    entry point of an aggregate which ensures the integrity of the entire graph Invariant A condition that should always be true for the system to be in a consistent state Persistence Ignorant Classes Classes that have no knowledge about how they are persisted
  13. Aggregates Design Rules Protect business invariants inside Aggregate boundaries. Design

    Small Aggregates Reference other Aggregates by Identity Use Eventual Consistency outside the Aggregate’s boundary
  14. Reference Other Aggregates by Identity Tempted to modify it within

    the same transaction. If Aggregates are referenced directly, query performance will be affected.
  15. Design small aggregates Large cluster limits scalability and performance Limit

    the Aggregate to Aggregate Root and several Value Typed (prefer Value Objects over Entities) Attributes or any other necessary minimum. Necessary means – those attributes which must be consistent with others. Don’t be confused by "has" relationship
  16. Identify services 1 Start from ubiquitous language 2 Identify business

    operations inside domain 3 Distinguish between infrastructure and domain
  17. Modeling Events Domain Events and their properties should be named

    according to the Ubiquitous Language in the Bounded Context where they originate. If an Event is the result of executing a command operation on an Aggregate, the name is usually derived from the command that was executed. Example: Command operation: Product.planBacklogItem(…) Event outcome: ProductBacklogItemPlanned Other Examples: User Authenticated, PaymentReceived, , ItemCheckedOut
  18. Use Eventual Consistency Outside the Boundary • When a command

    on a single Aggregate necessitates the enforcement of additional business rules on one or more other Aggregates, apply eventual consistency. • Utilize the Event triggered by the initial Aggregate’s command to update other Aggregates to a consistent state through separate transactions.
  19. Use Eventual Consistency Outside the Boundary For example, committing a

    backlog item to sprint requires updating two aggregates: Sprint and BacklogItem. First, BackLogItem is updated. BackLogItem raises the corresponding event: Based on: Vaughn’s Vernon Aggregates Design Rules essay: https://vaughnvernon.co/wordpress/wp-content/uploads/2014/10/DDD_COMMUNITY_ESSAY_AGGREGATES_PART_2.pdf Shared under Creative Commons Attribution-NoDerivs 3.0 Unported License - http://creativecommons.org/licenses/by-nd/3.0/ public class BacklogItem extends ConcurrencySafeEntity { ... public void commitTo(Sprint aSprint) { ... DomainEventPublisher .instance() .publish(new BacklogItemCommitted(this.tenantId(), this.backlogItemId(), this.sprintId())); } ... } public class BackLogItemApplicationService { public void commitBacklogItemToSprint( String aTenantId, String aBacklogItemId, String aSprintId) { TenantId tenantId = new TenantId(aTenantId); BacklogItem backlogItem = backlogItemRepository().backlogItemOfId( tenantId, new BacklogItemId(aBacklogItemId)); Sprint sprint = sprintRepository().sprintOfId( tenantId, new SprintId(aSprintId)); backlogItem.commitTo(sprint); this.backlogItemRepository().save(backlogItem); ... } }
  20. Use Eventual Consistency Outside the Boundary (Continuing the example) Then,

    BackLogItemCommitted event is handled to update the Sprint Aggregate: Based on: Vaughn’s Vernon Aggregates Design Rules essay: https://vaughnvernon.co/wordpress/wp-content/uploads/2014/10/DDD_COMMUNITY_ESSAY_AGGREGATES_PART_2.pdf Shared under Creative Commons Attribution-NoDerivs 3.0 Unported License - http://creativecommons.org/licenses/by-nd/3.0/ public class Sprint extends ConcurrencySafeEntity { public void commit(BacklogItem aBacklogItem) { int ordering = this.backlogItems().size() + 1; CommittedBacklogItem committedBacklogItem = new CommittedBacklogItem( this.tenantId(), this.sprintId(), aBacklogItem.backlogItemId(), ordering); this.backlogItems().add(committedBacklogItem); } } public class SprintApplicationService { public void handle(BacklogItemCommitted backLogCommittedEvent) { backlogItem backlogItem = backlogItemRepository().backlogItemOfId( backLogCommittedEvent.tenantId(), backLogCommittedEvent.backlogItemId()); Sprint sprint = sprintRepository().sprintOfId( backLogCommittedEvent.tenantId(), backLogCommittedEvent.committedToSprintId()); sprint.commit(backlogItem); this.sprintRepository().save(sprint); } }
  21. Eventual consistency options • Synchronous • The transaction that updates

    the second Aggregate commences immediately after the first Aggregate has been updated. • Advantages • Minimizes the duration of inconsistency • Does not depend on specialized tools • Disadvantage: may encounter difficulties when handling failover scenarios during implementation
  22. Eventual consistency options • Asynchronous • The transaction that updates

    the second Aggregate occurs after a delay determined by the messaging system used. • Advantage: multiple established solutions are available (such as NServiceBus) • Disadvantage: the duration of inconsistency is extended
  23. Summary of Key Points • Tactical design aligns domain models

    closely with business needs. • Strategies for discovering entities and services • Entities and aggregates - transactional consistency and identity. • Domain services and events support business operations beyond entities. • Validation rules - integrity at property, object and aggregate levels. • Strategy for designing aggregates. 9/24/2025 36
  24. Contact Information For further inquiries or discussions, reach out anytime.

    medium.com/@adelinastanciu Adelina Stanciu 9/24/2025 37