raulo5

Domain Driven Design

Quotes and notes

Tackling Complexity in the Heart of Software

by Eric Evans

https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/

About Complexity in Software

…the heart of this complexity is the essential intricacy of the problem domain itself.

  • It’s all about the Domain

  • Concepts and implementation goes together

  • We need to be able to include the Domain in all our discussions… but how?

  • Ubiquitous Language helps communicate Tech and Business back and forth in Knowledge Crunching Sessions (which in turns makes Ubiquitous Language and therefore the Domain Model better over time)

Made with https://www.mural.co/Made with https://www.mural.co/

The greatest value of a domain model is that it provides a ubiquitous language that ties domain experts and technologists together.

An approach to tackle Software Complexity

  • Close relationship and collaboration between Domain and Technology teams

  • Build a model that keeps relevant to the problem to be solved

  • Keep it iterative, so the model can evolve

  • Over time, model and ubiquitous language will evolve together

  • Distilling the model: Important concepts are added to the model as well as other non relevant concepts are dropped.

  • Continuous Knowledge-Crunching produces Knowledge-Rich Design

On Ubiquitous Language

https://www.pexels.com/https://www.pexels.com/

Developers even translate for each other. Translation muddles model concepts, which leads to destructive refactoring of code. … Translation blunts communication and makes knowledge crunching anemic.

  • The model should feed both discussions for developers and domain experts

  • Try to keep Ubiquitous Language and Model in sync

  • How to test the Ubiquitous Language? Get Developers and Domain Experts together and ask them to walk thru common scenarios.

  • In code, Ubiquitous Language can be expressed also using Intention-Revealing Interfaces (meaning: naming classes and operations describing purpose, which are close to the Business Domain jargon)

  • Design by Contract may help (stating pre/post conditions and invariants) designing explicit behaviour.

The Building Blocks of a Model-Driven Design

Made with https://app.mural.co/Made with https://app.mural.co/

Entities

  • Defined by ID

  • Not defined by their attributes.

  • Have a tread of continuity (a lifecycle)

  • Has an operational way to distinguish from another entity

Value Objects

  • Has no identity

  • Has no lifecycle

  • Has attributes to describe things

  • Should be safely/easily shareable: Should be immutable

FACTORIES to create and reconstitute complex objects and AGGREGATES, keeping their internal structure encapsulated. Finally, REPOSITORIES address the middle and end of the life cycle, providing the means of finding and retrieving persistent objects

Aggregates

  • Collection of related Entities and/or Value Objects

  • Has an Aggregate Root

Factories

  • Create and reconstitute Entities (and Aggregates)

  • May check invariants, but it is usually better to delegate this check to the product

Repositories

  • Handles storage for Entities (handling part of the related Life Cycle)

  • Manages conceptual domain objects as sets

Now from a technical point of view, retrieval of a stored object is really a subset of creation, because the data from the database is used to assemble new objects.

Services

  • Holds stand alone operations related to the domain concepts

  • Is stateless

  • The interface is defined in terms of other elements of the domain (usually entities and/or value objects)

Associations

For every traversable association in the model, there is a mechanism in the software with the same properties.

To keep associations under control:

  • Add traversal direction

  • Add qualifier to reduce multiplicity

  • Eliminate non esencial association

About Packaging

  • Layered Architecture places Infrastructure and User Interface into separate packages, leaving the Domain related code into it’s own packages

  • Packaging should separate Domain code separated from the rest of the code

  • Modularity becomes critical when Domain gets bigger / more complex

Lifecycle of an Entity

Keeping a healthy lifecycle for an entity has some concerns we need to care about:

  1. Maintain integrity

  2. Keep lifecycle related operations simple and predictable

Made with https://app.mural.co/Made with https://app.mural.co/

In any system with persistent storage of data, there must be a scope for a transaction that changes data, and a way of maintaining the consistency of the data (that is, maintaining its invariants).

Specifications

Modelling constraints explicitly improves design. This is challenging because constraints are not easy to foresee even during knowledge crunching sessions.

Specification: It’s a Constrain modelled as predicate-like Value Objects.

A SPECIFICATION is a predicate that determines if an object does or does not satisfy some criteria.

This Specification can be used to hold a Business Rule in the Domain layer, and may serve to one of these purposes:

  1. Validate an object (Value Object or Entity) against a Business Rule

  2. Select an object from a collection (so here the Business Rule act as a Filter)

  3. Specify how a new object needs to be created.

Core Domain

To make the domain model an asset, the model’s critical core has to be sleek and fully leveraged to create application functionality.

Parts of the model that can be identified as unique and central to the business make up the Core Domain.

Cohesive subdomains (which are not part of the core business) can be separated in Modules.

Some times this Core Domain is called also Shared Kernel, when it has parts that need to be shared with other Subdomains.

Bounded Context

Bounded Context is the way DDD deals with big models, where a single Bounded Context refers to a part of the model tackling a specific part of the business.

By explicitly defining a BOUNDED CONTEXT within which a model applies and then, when necessary, defining its relationship with other contexts, the modeler can avoid bastardizing the model. BOUNDED CONTEXTS allow work to proceed in different parts without corrupting the model or unintentionally fragmenting it.

A Context Map should help showing all the Bounded Contexts and how the are related.

Continuous Integration is also a practice that is beneficed: You can easily focus on running CI separately by Bounded Context.

That’s it (: