Today's applications are undoubtedly sophisticated and rely on many technologies to do what they do. As developers we focus more on the technical implementation of the software, starting from what language, framework or tool we use for the implementation.
This happens because developers are problem solvers and enjoy this part of the job. But, the truth is that a system that doesn't solve the business need is of no use to anyone, no matter how pretty it looks or how well-architected it is implemented.
When we think about a project, there are many things which can delay that project: for example bureaucracy, unclear objective, lack of resources and so on.
The design of the system largely determines how complex the software can become. When the complexity of the system is too high, it can get out of hand for developers and this can make changes and extensibility to become a hard task. A good design can create opportunities that exploit those complex features. The complexity of many applications is not technical. What is technical is the domain itself, the activity or business of the user.
The concept of domain-driven design (DDD) is about placing our attention at the heart of the application, focusing on the complexity that is intrinsic to the business domain itself. We also distinguish the code domain (unique to the business) from the supporting sub-domains (typically generic in nature, such as money or time), and place our design efforts on the core more.
The premises for domain driven design is that each software application should be based on a model, model based on domain and domain logic instead of the technology that is being used. By focusing on this model, it is easier to achieve a shared terminology between domain experts and developers, breaking down the language barriers that often exist between them.
Domain driven design is not a technology or a method, but a mind set and a set of priorities. In order to achieve faster development of software using domain driven design, we must choose a set of design principles, design patterns and best practices.
It does not matter if the domain complexity is not handled in the design, as long as the infrastructure technology is well conceived. A successful design must systematically deal with this central aspect of the software. Every application relates to some activity or interest of its user. That subject area to which the user applies the program is the domain of the application. Some domains involve the physical word, for example airline-brooking programs involve real people getting on real aircrafts.
We can have domains which are intangible, for example the domains for an accounting program are money and finance. For creating a software which is valuable for the user, development must create a body of knowledge related to the user's activity. It can be hard to gain this body of knowledge because the volume and complexity of information can be overwhelming.
Models are useful tools in this respect. A model is a selectively simplified and consciously structured form of knowledge. A good model makes sense of information and focuses on a problem. A domain model is not a particular diagram. It is the idea that diagram is intended to convey. It is not just the knowledge in a domain expert head. It is a rigorously organized and selective abstraction of that knowledge. A diagram can represent and communicate a model, as can carefully written code, as can an English sentence.
Domain modelling is not a matter of making a model as "realistic" as possible. Even in a domain of tangible real-world things, our model is an artificial creation. In domain-driven design we have three basic uses that determine the choice of a model.
The model is distilled knowledge. The teams' agreed-upon way of structuring domain knowledge and distinguishing the elements is based on model. A model captures how we choose to think about the domain as we select terms, break down concepts and relate them. Because of a shared language, developers and domain experts can collaborate effectively as they wrestle information in the shared language. The binding of model and implementation makes experience with early versions of the software applicable as feedback into the modeling process.
The model is the backbone of a language used by all team members. Because of the binding of model and implementation, developers can talk about application in this language. The communication between developers and domain experts can be done without translation. If the language is based on the model, our natural linguistic abilities can be turned on to refine the model.
The model and the heart of the design shape each other. The link between model and implementation makes the model relevant and ensures that the analysis that went into it applies to the final product, an application. The binding between model and implementation helps a lot during maintenance and continuing development, because the code can be interpreted based on understanding the model.
The heart of software is its ability to solve domain-related problems for its users. The basic purposes are supported by all other features. Solving domain-related problems for a complex domain is a difficult task for talented and skilled people. The modeling of domain problems is not a priority for most software projects. Most developers are not interested in learning about the specific domains in which they are working, much less make a major commitment to expand their domain-modeling skills.
Many technical people enjoy problems that exercise their technical skills. Domain work is messy and demands a lot of complicated new knowledge that doesn't seem to add capabilities to a computer scientist's knowledge. Technical people go and work to elaborate the code in order to solve domain problems, and the learning about domain modeling is left to others. Complexity in the heart of software has to be tackled head-on.
Domain developments hold opportunities to cultivate very sophisticated design skills. The messiness of most software domains is actually an interesting technical challenge. In many scientific disciplines "complexity" is one of the most exciting topics, as researches attempt to tackle the messiness of the real world. To start developing an application based on domain problems, developers need to "crunch" the knowledge about the problem. Effective domain modelers are knowledge crunchers. In knowledge crunching, we need to take a torrent of information and probes to obtain the relevant details about that problem.
Each idea needs to be organized one after another, to be simplified to make sense out of the mess. In this process, many models are tried, rejected or transformed. Success comes in an emerging set of abstract concepts that makes sense of all the detail. The distillation is a rigorous expression of the particular knowledge that has been found most relevant.
In the old waterfall development method, the business experts talk to the analysts, analysts digest and transform the information from business experts and pass the result to developers which implement the software. This approach fails because it lacks feedback. The analysts had the full responsibility to create the model based on input from business expert. This caused a lack of communication between analysts and developers, and, as a result, the learning opportunities for both parties were very few.
Business activities and rules are as central to a domain as are the entities involved. Any domain will have various categories of concepts. In parallel with model change, developers refactor the implementation to express the model, giving the application use of that knowledge. When moving beyond entities and values, knowledge crunching can get intense, because there can be many inconsistencies among business rules.
The core of a common language from a software project is based on domain models. The model is a set of concepts built up in the heads of the developers involved in the project, with terms and relationships that reflect domain insight.
The semantics of the language is based on terms and interrelationships tailored to the domain, while being precise enough for technical development. This is a crucial cord that weaves the model into the development activity and which binds it with the code.
The model-based communication is not limited to diagrams in the Unified Modeling Language (UML). In order to use a model efficiently, it needs a common medium of communication at all levels. Having this common language helps in the editing of documentation and of informal diagrams. In addition, this improves communication through the code and through the tests for the code.
Domain experts have limited understanding of the technical jargon used by software developers and have a jargon for themselves in order to communicate about a given domain. On the other hand, developers understand and discuss the system in descriptive, functional terms which are different from the terms used by domain experts. In other cases, developers create abstractions that support their design, but are not understood by domain experts. Both developers and domain experts work on different sides of the same problem.
Across this linguistic divide, the domain experts vaguely describe what they want. Developers struggle to understand a domain which is new to them and which they vaguely understand. On a project without a common language, developers have to translate for experts. Domain experts translate between developers and other domain experts. Even developers translate for each other. A project faces serious problems when its language is fractured. In a project where language is fractured, the terminology of day-to-day discussions is disconnected from the terminology embedded in the code (ultimately the most important product of a software project).
Each part of the team uses their jargon, domain experts use their jargon while the technical team have their own language. The overhead cost of all translation between jargons is very high and there is also a higher risk of misunderstanding. A project needs a common language that is more robust than the lowest common denominator. With effort from the team, the domain model can provide the backbone for that common language, while connecting team communication to the software implementation.
The same model should supply the language for developers and domain experts so that they can communicate with each other, and for domain experts to communicate among themselves about requirements, development planning and features.
For best results in using domain driven design, we need to use the model as the backbone of a language. Each team needs to exercise that language in all communication within the team and in the code. Teams need to use the same language in diagrams, in writing and especially in speech.
Contrary to projects with no domain models, there are complex projects which are attempting some sort of domain model. However, they don't maintain a tight connection between the model and the code. The models developed as part of this project can be useful as some kind of exploratory tools, but, in time, the model can become irrelevant and even misleading.
The bind between the code and models can be broken down in many ways, but very often this is a conscious choice. Many existing design methodologies use an analysis model, which is quite distinct from the design and usually developed by different people. It is called analysis model because it is the product of analyzing the domain business with the purpose of organizing the concepts related to business and without any consideration for the part it will play in an implementation.
We saw that the main purpose of domain-driven design is to analyze and to model the entire domain problem using domain-model. A domain-model represents a key concept deriving from domain problem. In addition, DDD comes with the idea of a common language used by the development team and the business experts.
This common language needs to be created when you work with domain-models in order to make the work easier for both parts. After defining the domain-model and a common language, the DDD suggests that we need to create a bind between domain-model and code, and to maintain this bind in the development process. This bind, if used properly, creates a good process to be followed by development. The result is that, when the implementation is modified, this is reflected in the domain-model and vice versa. This process helps the project be up to date at all times, with changes during development for both business experts and the development team.
Domain-Driven Design is a very good approach to use in the daily development process, because of a good set of rules and processes which can help a software application be developed faster and be maintained very easily.
by Cassian Lup
by Claudia Mihu
by Oana Călugar
by Mircea Vădan