As a rule, we work according to the so-called domain-driven design principle.
Domain-driven design (DDD) is an approach to software development for complex needs by connecting the implementation to an evolving model. The premise of domain-driven design is the following:
– placing the project’s primary focus on the core domain and domain logic;
– basing complex designs on a model of the domain;
– initiating a creative collaboration between technical and domain experts to iteratively refine a conceptual model that addresses particular domain problems.
Ideally, it would be preferable to have a single, unified model. While this is a noble goal, in reality it typically fragments into multiple models. It is useful to recognize this fact of life and work with it.
Strategic Design is a set of principles for maintaining model integrity, distillation of the Domain Model and working with multiple models.
In the book Domain-Driven Design, a number of high-level concepts and practices are articulated, such as ubiquitous language meaning that the domain model should form a common language given by domain experts for describing system requirements, that works equally well for the business users or sponsors and for the software developers. The book is very focused on describing the domain layer as one of the common layers in an object-oriented system with a multilayered architecture. In DDD, there are artifacts to express, create, and retrieve domain models:
An object that is not defined by its attributes, but rather by a thread of continuity and its identity.
Example: Most airlines distinguish each seat uniquely on every flight. Each seat is an entity in this context. However, Southwest Airlines, EasyJet and Ryanair do not distinguish between every seat; all seats are the same. In this context, a seat is actually a value object.
An object that contains attributes but has no conceptual identity. They should be treated as immutable.
Example: When people exchange business cards, they generally do not distinguish between each unique card; they only are concerned about the information printed on the card. In this context, business cards are value objects.
A collection of objects that are bound together by a root entity, otherwise known as an aggregate root. The aggregate root guarantees the consistency of changes being made within the aggregate by forbidding external objects from holding references to its members.
Example: When you drive a car, you do not have to worry about moving the wheels forward, making the engine combust with spark and fuel, etc.; you are simply driving the car. In this context, the car is an aggregate of several other objects and serves as the aggregate root to all of the other systems.
A domain object that defines an event (something that happens). A domain event is an event that domain experts care about.
When an operation does not conceptually belong to any object. Following the natural contours of the problem, you can implement these operations in services. See also Service (systems architecture).
Methods for retrieving domain objects should delegate to a specialized Repository object such that alternative storage implementations may be easily interchanged.
Methods for creating domain objects should delegate to a specialized Factory object such that alternative implementations may be easily interchanged.