Ubiquitous language
- A common language to help communication between software developers and domain experts.Invariant
- describes something that must be true with your design all the time.Bounded Context
- A specific responsibility enforced by explicit boundaries. These boundaries are set by the different way we represent models. Different contexts may have completely different models of common concepts with mechanisms to map between them.- A Bounded Context can be considered as a miniature application, containing it’s own Domain, own code and persistence mechanisms.
- Communication to and from a Bounded Context is done via a Context Map.
describe things in the domain model
Entity
- A unique thing that has a life cycle and can change state. For example, a conference in a conference management system will be an entity; many of its attributes could change over time (such as its status, size, and even name), but within the system each particular conference will have its own unique identity.Value object
- Not all objects are defined by their identity. For some objects what is important are the values of their attributes.- Sometimes in one context something is an entity while in another it is just a value object.
Services
- You cannot always model everything as an object.- it may make sense to model a third-party payment processing system as a service. The system can pass the parameters required by the payment processing service and then receive a result back from the service.
- A service in a DDD domain model is not a web service. It communicates aggregate roots, performs complex use cases, cross aggregates transaction. An operation offered as an interface that stands alone in the model, with no encapsulated state.
Aggregate
- Whereas entities, value objects, and services are terms for the elements that DDD uses to describe things in the domain model, the terms aggregate and aggregate root relate specifically to the lifecycle and grouping of those elements.- Aggregate is a cluster of domain objects that can be treated as a single unit to provide a specific functionality and for the purpose of data changes.
- Every aggregate has a unique ID; therefore, you can use that ID to record which aggregate in the system was the source of a particular event.
- In summary, aggregates are the mechanism that DDD uses to manage the complex set of relationships that typically exist between the many entities and value objects in a typical domain model.
Aggregate root
- An aggregate root (also known as a root entity) is the gatekeeper object for the aggregate. All access to the objects within the aggregate must occur through the aggregate root; external entities are only permitted to hold a reference to the aggregate root, and all invariants should be checked by the aggregate root.- An aggregate root is an entity that composes other entities (as well as its own values) by composition. It is the domain’s only entry point for data access. A heart of your domain.
- Another area where there can be confusion is in distinguishing entities from aggregates. Every aggregate has an entity acting as its aggregate root, and for lots and lots of entities the aggregate will consist of just this entity. The point is that "Customer have Orders" does not mean imply aggregation; Customer, Order and Product are all aggregate roots.
Domain Event
- A Domain Event is something that happened in the past, and that is of interest to the business.- Domain Events is an immutable array of Domain Event objects. Once they have been initialized, there's no way to change them, there are no setters. Because events happen in the past, they cannot be changed or undone. That makes perfect sense: History can't be altered!
- Events happen in the past. For example, "the speaker was booked," "the seat was reserved," "the cash was dispensed."
- Events can be processed multiple times, by multiple consumers.
- Here are sets of events we may come up with from the cafe tab scenario. TabOpened, DrinksOrdered, FoodOrdered, FoodCancelled, DrinksServed, FoodPrepared, FoodServed, TabClosed.
CQRS — Command-Query Responsibility Segregation
- A common sense rather than a pattern. CQRS just separates a model into two separate parts — READ model and WRITE model.- They also can be referenced as Query model and Command model. Segregation must be clean so commands can’t return any data.
- A command is any method that mutates state and a query is any method that returns a value.
- CQRS is not a top-level architecture. CQRS is something that happens at a much lower level.
Commands
- Commands are imperatives; they are requests for the system to perform a task or action. For example, "book two places for conference X" or "allocate speaker Y to room Z." Commands are usually processed just once, by a single recipient.- Commands are things that indicate requests to our domain.
- A command may be accepted or rejected.
- An accepted command leads to zero or more events being emitted to incorporate new facts into the system.
- A rejected command leads to some kind of exception.
- Commands are also identified by looking for verbs. For example OpenTab, PlaceOrder, MarkFoodServed, CloseTab etc. However, they are focused around what the user considers as an operation.
Exceptions
- An important part of the modeling process is thinking about the things that can cause a command to be refused. We are expected to model these "sad paths" into exception types, just as commands and events are expressed as DTOs.- Looking to the cafe domain scenario, we can identify three notable exceptions we need in our model: CannotCancelServedItem, TabHasUnservedItems and MustPayEnough. The names here try to explain why the command failed.
Command Bus
- The idea of a command bus is that you create command objects that represent what you want your application to do. Then, you toss it into the bus and the bus makes sure that the command object gets to where it needs to go.- So, the command goes in -> the bus hands it off to a handler -> and then the handler actually does the job. The command essentially represents a method call to your service layer.
- The Command Bus pattern relies on 3 types of classes:
Command (encapsulate our input, does simple validation on it)
CommandHandler (dedicated to a single Command, does the actual logic)
CommandBus (interface allowing us to build Middlewares that calls the appropriate CommandHandle for the given Command)
Query
— an interpreter, which is a structure of objects which can form itself into an SQL query. You can create this query by referring to classes and fields rather than tables and columns. In this way, those who write the queries can do so independently of the database schema and changes to the schema can be localized in a single place.Event Sourcing
- Event sourcing is a way of persisting your application's state by storing the history that determines the current state of your application. For example, a conference management system needs to track the number of completed bookings for a conference so it can check whether there are still seats available when someone tries to make a new booking.- ensuring every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself.
Repository
- mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.- A mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects.
- pretends to be a collection of Aggregate Roots.
https://developer-paradize.blogspot.com/2016/05/ddd-building-blocks-dictionary.html
https://blog.lelonek.me/ddd-building-blocks-for-ruby-developers-cdc6c25a80d2