The domain design approach to software development contributes to solving a specific domain model. It revolves around the business model, linking execution to key business principles.
Now we will share some tips for developers interested in using Domain-Driven Design (DDD) coding patterns.
In the article below we will cover the following series of issues:
The main focus of such patterns is on the business sphere, and alongside they make up Domain-Driven Design. And we can say that final templates are the result of your skill in business modeling.
Why is DDD so important?
Here is a shortlist of the main benefits of DDD.
Consistency with a business model, strategies, and processes.
Isolation from other spheres and layers of the business.
No dependencies of any application tier on either side of the domain tier.
Reusability to avoid duplicated models.
The ability to avoid the drawbacks of frameworks and tight coupling with external frameworks.
Ability to be layered and to be developed without any technology or infrastructure dependencies.
Domain-Driven Design is an attitude to IT development that facilitates the complexities faced by developers as they integrate into a progressing model.
Here we have a domain, bounded contexts, and a unified responsibility principle. Every single component could be commuted with another outside the domain. An ability to add or eliminate from the software without a hitch — is how DDD works, so it’s important to use it for IT developers and entrepreneurs.
DDD aims are:
The domain-based design process involves close interaction between the developers and customers. A common model with common languages is important so that when people with various perspectives talk over a solution, they have a common base with common concepts.
At the same time, insufficient understanding among the developer and the customer, as well as the ignorance in the subject field, exacerbate errors in the system. Correction of such errors is usually expensive if they are discovered late.
Developers cannot create software without first comprehending the customer’s requirements. DDD places good emphasis on not only understanding what are the customer’s requirements but also cooperation with him as partners on the particular project. An ultimate goal is not just to create code or not even to create software and solve issues that meet the best benefits of your customer!
What about Domain Modeling?
Domain modeling is about focusing on business objectives. When designing types, their properties, and behaviors, the development team really need to consider how relationships will work inside the database and what the preferred object-relational mapping (ORM) framework will be to handle properties, relationships, and inheritance hierarchies.
Unless you’re building software for a data storage and retrieval company — something like Dropbox — then saving data only plays a supporting role in your application.
Your data can be quite complex and complex. But with DDD’s approach to bounded contexts, persistence can be much less complex than systems that can be built without it.
If a developer knows how to set up database mappings using the Entity Framework Fluent AP in their ORM, they can make persistence work as needed. In the worst case, he might need to make some changes to the classes. If the database is out of date, it is possible to add a persistence model to map the database. Then use something like AutoMapper to solve issues between the domain model and the persistence model.
But all these difficulties are not related to the business problem that your software aims to accomplish. Therefore, it should not get in the way of domain design. Here can get up a problem when a developer is designing entities. Then he won’t be able to help but think about how EF will output mappings to databases. And therefore it is necessary to drown out the noise.
How does domain-specific design fit into the product life cycle?
This model characterizes the base of the business field of your organization. If the project team operates on a strategy with a common perception of the subject area, this eliminates risks and can increase the validity of the software being developed.
It is assumed that domain models will develop and change as the problem area develops. It is customary to initiate an interaction with a general picture of the area of activity of the organization.
Through this research, the team reaches a general agreement and certain agreements. It is this consensus that is the foundation on which developments can be built.
It helps everyone involved in the development process to figure out its potential value, as well as more focused work on the project.
As a product enters the early development phase, working out the domain and developing a universal language becomes a main part.
The key point here is that everyone involved tries to keep the models as connected as possible. In DDD, that’s logical to avoid developing overarching enterprise data models. Typically, data models work towards establishing the domain easier to interact with others and keeping the model flexible as much as possible over time.
Methods of managing your entities.
There is a fairly correct rule to make property setters proprietary.
The calling code is not allowed to arbitrarily set various properties. Cooperation with DDD objects and their associated data must be controlled using methods that modify properties.
To avoid building any new instance of Customer each time and setting it the same properties, we can apply some predefined rules using the Factory Pattern method, or even have a Create method for the Customer type.
The image demonstrates the type Customer defined according to the DDD template for the parent element.
Customer properties have their own setters, so only other members of this class can directly affect those properties. The class provides a constructor to manage its instance and hides the parameterless constructor.
Sometimes all you need is CRUD.
Not everything in applications needs to be created with DDD. If all you need to do is perform a random edit or query, then a simple class (or set of classes) is defined using properties and relationships. Sometimes DbContext is just all you need.
So, to perform an establishment of order with all of its positions, developers can use DDD to work with special business rules.
For example, it needs to know if the customer who placed the order has a VIP status? To do this, you have to get some information about the client. If the answer is yes, then apply a 15 percent discount to every item added to the order. Or need to find out if the user-provided their credit card information?
The key point in DDD is to incorporate domain logic into entity classes, taking advantage of OOP rather than implement “transactional scripting” in stateless business objects. This is what a general Code First demo class looks like.
Most often, your actions are something very standard, for example, creating a contact record for a user: name, address, email, etc. and save it. It’s just creating, reading, updating, and deleting (CRUD). You don’t need to create roots and behaviors for this.
More often than not, your application is a mixture of complex attitude and mere CRUD.
There is no need to waste time, energy, and money on the architecture of simple parts of your application. It is always important to define borders between different subsystems or bounded contexts. A single bounded context can be largely data-driven, while a crucial context limited to the main domain must, on the other hand, be designed according to DDD approaches.
Shared data in complex systems.
Another point worth paying special attention to is the issue of sharing types and data between subsystems. It is quite obvious that you need to separate types in different systems, and that all these types interact with the same table in the one database.
Mapping from different subsystems to one table or even one database can be irrational. This becomes clear if we consider as an example the sharing of a contact that has common data in different systems. How do you reconcile and use version control for the type of contact you might need on many systems? What if one system needs to replace the definition of this contact type? As far as the ORM is concerned, how do you map a contact which is used in different systems to one table in the same database?
Is it worth duplicating the first and last name of a person in several charts or even in several databases that are intended for different subsystems of your software solution? By eliminating the comprehensiveness of data sharing, you greatly simplify the work of building up your system. In any case, you should always minimize the duplication of data in tables. Sometimes you just need a user ID and its status to calculate its discounts. The first and last names of the same customer may only be needed in a contact management context.
But there is still a lot of information that needs to be shared between systems. You can use what DDD calls the “anti-corruption layer” by creating a new contact. Then you can make sure that this client is added for the first time. Or, on the contrary, a client with such an identification key already exists in another subsystem.
Domain-Driven Design promotes efficient communication.
Domain-Driven Design with no doubts is an effective way of writing clean, comprehensible code to solve assigned tasks.
Customers usually do not really care about how exactly the code works, but they do care about a high-quality, working final product. This means that effective dialogue with the customer regarding his needs for product features without extra technical components is a serious advantage that DDD can offer.