Domain-Driven Design is nothing magical but it is crucial to understand the importance of Ubiquitous Language, Domain Modeling, Context Mapping, extracting the Bounded Contexts correctly, designing efficient Aggregates and etc. before your next DDD project. Follow along and learn the 37 most common and advanced DDD, BDD and CQRS Interview Questions and Answers every Software Architect and Senior Developer must understand before the next Tech Interview.
Domain Driven Design is a methodology and process prescription for the development of complex systems whose focus is mapping activities, tasks, events, and data within a problem domain into the technology artifacts of a solution domain.
The emphasis of Domain Driven Design is to understand the problem domain in order to create an abstract model of the problem domain which can then be implemented in a particular set of technologies. Domain Driven Design as a methodology provides guidelines for how this model development and technology development can result in a system that meets the needs of the people using it while also being robust in the face of change in the problem domain.
The process side of Domain Driven Design involves the collaboration between domain experts, people who know the problem domain, and the design/architecture experts, people who know the solution domain. The idea is to have a shared model with shared language so that as people from these two different domains with their two different perspectives discuss the solution they are actually discussing a shared knowledge base with shared concepts.
Simpler communication:
More flexibility:
The domain is more important than UI/UX:
UX, using the DDD approach means that the product targets exactly the users that are directly connected to the domain.Ubiquitous language and Unified Model Language (UML):
Multilayered architecture is a common solution for Domain-Driven Design and contains four layers:
Artifacts used in Domain-Driven Design to express, create and retrieve domain models mapping business domain concepts into software artefacts. It’s about organizing code artifacts in alignment with business problems, using the same common, ubiquitous language. Some of the artefacts are:
The Domain Model is a software model of the very specific business domain you are working in. Often it's implemented as an object model, where those objects have both data and behavior with literal and accurate business meaning.
Creating a unique, carefully crafted domain model at the heart of a core, strategic application or subsystems essential to practicing DDD. With DDD your domain models will tend to be smallish, very focused. Using DDD, you never try to model the whole business enterprise with a single, large domain model.
A Specification represents a business rule that needs to be satisfied by at least part of the domain model,
You can also use Specification for query criteria
For example:
Color could be a value type where color type does not hold any meaning in itself but when attached to an entity like a shirt or a car (for example a red shirt or a black shirt) which mean something in the domain.On the contrary, an entity has a lifecycle. These are the types that are mutable and go through changes through different lifecycle events.
Order could be an entity that goes through different lifecycle events such as item added to order or item removed from order.
Each lifecycle event mutates the entity.Event Sourcing is a pattern for the recording of state in a non-destructive way. Each change of state is appended to a log. Because the changes are non-destructive, we preserve the ability to answer queries about the state of the object at any point in its life cycle.
Event Sourcing is not necessary for CQRS. You can combine Event Sourcing and CQRS. This kind of combination can lead us to a new type of CQRS. It involves modelling the state changes made by applications as an immutable sequence or log of events.
A Repository represents all objects of a type as a conceptual set (usually emulated). It acts like a collection, except with more elaborate querying ability. Objects of the appropriate type are added and removed, and the machinery behind the repository inserts them or deletes them from the database.
For each type of object that requires global access, create an object that can provide the illusion of an in-memory collection of all objects of that type. The primary use case of a repository: given a key, return the correct root entity. The repository implementation acts as a module, which hides your choice of persistence strategy.
For each aggregate root (AR) you should have a repository. As a minimum the repository would probably have a void Save(Aggregate aggregate) and a Aggregate Get(Guid id) method. The returned aggregate would always be fully constituted.
User Interface (or Presentation Layer):
Application Layer:
Domain Layer (or Model Layer):
Infrastructure Layer:
There are different ways to create a unique identity for objects:
Benefits of CQRS include:
Bounded Contexts have both unrelated concepts (such as a support ticket only existing in a customer support context) but also share concepts (such as products and customers). Different contexts may have completely different models of common concepts with mechanisms to map between these polysemic concepts for integration. Several DDD patterns explore alternative relationships between contexts.
Consider:
By applying DDD we first try to study and understand the domain (or field) we work on. One of the practices (taken from XP) would be the writing of stories that occur in the problem domain. From these you can identify your use cases and objects for your design. They emerge and tell you what needs to be in the solution, and how they will need to interact with each other.
The concepts described by the UL will form the basis of your object-oriented design and system artifacts. DDD provides some clear guidance on how your objects should interact, and helps you divide your objects into the following categories:
By practicing DDD and exploring business domain, you build a ubiquitous language (UL), which is basically a conceptual description of the system that implements the solution.
In order to create good software, you have to know what that software is all about. You cannot create a banking software system unless you have a good understanding of what banking is all about, one must understand the domain of banking.
Domain is the field for which a system is built. Airport management, insurance sales, coffee shops, orbital flight, you name it.
It's not unusual for an application to span several different domains. For example, an online retail system might be working in the domains of shipping (picking appropriate ways to deliver, depending on items and destination), pricing (including promotions and user-specific pricing by, say, location), and recommendations (calculating related products by purchase history).
Event storming is not a notation. It's a very interactive team practice based on sticky notes put on a board and rearranged as the modelling progresses. It starts with the identification of the events, seeks the commands that cause them, and then looks at the involved aggregates/entities. It engages both Domain Experts and developers in a fast-paced learning process.
The output of an event storming describes the domain using the following DDD concepts:
A model is a useful approximation to the problem at hand.
An Employee class is not a real employee. It models a real employee. We know that the model does not capture everything about real employees, and that's not the point of it. It's only meant to capture what we are interested in for the current context.
Different domains may be interested in different ways to model the same thing. For example, the salary department and the human resources department may model employees in different ways.
In traditional architectures, the same data model is used to query and update a database. That's simple and works well for basic CRUD operations.
CQRS stands for Command and Query Responsibility Segregation, a pattern that separates read and update operations for a data store. CQRS separates reads and writes into different models, using commands to update data, and queries to read data.
The canonical definition of a DTO is the data shape of an object without any behavior. Generally DTOs are used to ship data from one layer to another layer across process boundries.
ViewModels are the model of the view. ViewModels typically are full or partial data from one or more objects (or DTOs) plus any additional members specific to the view's behavior (methods that can be executed by the view, properties to indicate how toggle view elements etc...). In the MVVM pattern the ViewModel is used to isolate the Model from the View.
DDD focuses on defining the vocabulary in that language: actors, entities, operations, ... An important part of DDD is also that the ubiquitous language can be clearly seen in the code, too, not only in communication between the implementor and the domain expert. So an extreme view of DDD is quite static: it describes the finished system as a whole.
BDD focuses on defining user stories or scenarios. It is closely related to an incremental process, but it can also be viewed as static: it describes all the interactions between users and the finished system.
DDD and BDD can be applied with no overlapping: BDD user stories can be written using only UI vocabulary (buttons, labels, ...), and DDD can avoid mentioning interactions.
But ideally these two overlap and work together: the BDD stories are rich in the ubiquitous language, describing the user experience with domain concepts. And DDD makes sure the stories can be found in the code.
POCO - Plain Old %Insert_Your_Language% Object. A type with no logic in it. It just stores data in memory. You'd usually see just auto properties in it, sometimes fields and constructors.Domain Object an instance of a class that is related to your domain. I would probably exclude any satellite or utility objects from domain object, e.g. in most cases, domain objects do not include things like logging, formatting, serialisation, encryption etc - unless you are specifically building a product to log, serialise, format or encrypt respectively.Model Object I think is the same as Domain object. Folks tend to use this interchangeably.Entity a class that has idRepository a class that speaks to a data storage from one side (e.g. a database, a data service or ORM) and to the service, UI, business layer or any other requesting body. It usually hides away all the data-related stuff (like replication, connection pooling, key constraints, transactions etc) and makes it simple to just work with dataService a class (or microservice) that provides some functionality usually via public API. Depending on the layer, it can be for example a RESTful self-contained container, or class that allows you to find a particular instance of needed type.Think of:
Value Objects as static data that will never change
ColorEntities as data that evolves in your application
CustomerDomain-Driven Design (DDD) is divided into strategic patterns and tactical patterns:
Consider:
According Eric Evans Domain-Driven Design:
When a significant process or transformation in the domain is not a natural responsibility of an ENTITY or VALUE OBJECT, add an operation to the model as standalone interface declared as a SERVICE. Define the interface in terms of the language of the model and make sure the operation name is part of the UBIQUITOUS LANGUAGE. Make the SERVICE stateless.
These types of services can be identified more specifically as domain services and are part of the domain layer. Domain services are different from infrastructural services because they embed and operate upon domain concepts and are part of the ubiquitous language.
Basically Aggregates help:
Rust has been Stack Overflow’s most loved language for four years in a row and emerged as a compelling language choice for both backend and system developers, offering a unique combination of memory safety, performance, concurrency without Data races...
Clean Architecture provides a clear and modular structure for building software systems, separating business rules from implementation details. It promotes maintainability by allowing for easier updates and changes to specific components without affe...
Azure Service Bus is a crucial component for Azure cloud developers as it provides reliable and scalable messaging capabilities. It enables decoupled communication between different components of a distributed system, promoting flexibility and resili...