4
Model-Driven Design

WHAT’S IN THIS CHAPTER?

  • The definition of a domain model
  • Binding a code model to the analysis model using a ubiquitous language
  • The importance of a ubiquitous language
  • How to collaborate on a ubiquitous language for improved communication
  • Tips on how to create effective domain models
  • When you should apply Model-Driven Design

With a deep and shared understanding of the problem domain, along with insight into the core areas that are fundamental to the success of an application, you are now able to focus on the solution space. However, it is important to implement in code the analysis model that was produced during knowledge-crunching sessions; i.e., the model that the business understands. Traditional software processes keep the code model and analysis model separate, which leads to an implementation that rarely resembles the blueprint due to new insight and constraints of the technical solution. DDD acknowledges the need to produce a single model that serves as an analysis model for business people to understand and which is implemented using the same terminology and concepts in code.

This process is known as Model-Driven Design and is heavily dependent on Ubiquitous Language to tie the technical implementation of the model to the analysis model and keep them in sync throughout the lifetime of the system. As well as detailing Model-Driven Design and Ubiquitous Language, this chapter also covers patterns to create effective domain models and the scenarios where Model-Driven Design should be used.

What Is a Domain Model?

The domain model, as shown in Figure 4.1, is at the center of Domain-Driven Design (DDD). It is formed first as an analysis model through the collaboration between a development team and business experts during knowledge-crunching sessions. It represents a view, not the reality, of the problem domain designed only to meet the needs of business use cases. It is described in a shared language that the team speaks and the diagrams that the team sketches. When it is expressed as a code implementation, it is bound to the analysis model through the use of the shared language. Its usefulness comes from its ability to represent complex logic and polices in the domain to solve business use cases. The model contains only what is relevant to solve problems in the context of the application being created. It needs to constantly evolve with the business to keep itself useful and valid.

images

FIGURE 4.1 The role of a domain model.

The Domain versus the Domain Model

The domain represents the problem area you are working within. It is the firm reality of the situation. The domain model, on the other hand, is an abstraction of the problem domain, expressed as a code implementation that represents a view, not the reality, of the problem. This difference is highlighted in Figure 4.2. The usefulness of the domain model comes in its ability to represent complex logic and polices in the domain to solve business problems and not how well it reflects reality. It also exists in a more abstract space: in the language the team speaks and the diagrams it sketches. The model is built from the collaboration between the development team and the business experts. The model contains only what is relevant to solve problems in the context of the application being created. It needs to constantly evolve with the business to keep itself useful and valid. The domain model only exists to help us solve problems; in order to be effective it needs to have clarity and be free of technical complexities. This way both the business and development teams can collaborate on its design.

images

FIGURE 4.2 The domain versus the domain model.

The Analysis Model

Also sometimes known as a business model, an analysis model is a collection of artifacts that describe the model of a system. These artifacts can be anything from cigarette packet sketches to informal UML. The analysis model exists to help both the development teams and business users to understand the problem domain; it is not a blueprint for the technical implementation.

The Code Model

DDD doesn’t advocate the removal of the analysis model. Far from it, because there is much value to be gained from a model that describes the system. Instead, DDD emphasizes the need to keep the code model, the implementation, in close synergy with the analysis model, the design. This synergy is achieved by ensuring both models are described and share the UL, as shown in Figure 4.3. The utopia is a single model that has value in both implementation and design. To achieve this, it is crucial to keep the code model clean of technical concerns and focused on the domain. In turn, it is important to have an analysis model that can be implemented—not too abstract or high level to be of any use.

images

FIGURE 4.3 The binding between the code and analysis model.

The Code Model Is the Primary Expression of the Domain Model

The code model is the realization of the analysis model; it validates the assumptions of the business and quickly highlights any inconsistencies with the analysis model. If, during the creation of the code model, issues are found and logic doesn’t seem to fit, the development team should work with the domain experts to resolve these problems. This update to the code model is reflected in the analysis model by making changes to work flow and polices that may not have exposed issues before. Likewise, any changes from a business perspective need to be reflected in the code model. The code and business models are kept in synergy. The code is the model; the code is the truth.

Model-Driven Design

Model-Driven Design is the process of binding an analysis model to a code implementation model, ensuring that both stay in sync and are useful during evolution. It is the process of validating and proving the model in practice, because it’s pointless to have an elaborate model if you can’t actually implement it. Model-Driven Design differs from DDD in that it is focused on implementation and any constraints that may require changes to an initial model, whereas DDD focuses on language, collaboration, and domain knowledge. The two complement each other; a Model-Driven Design approach enables domain knowledge and the shared language to be incorporated into a software model that mirrors the language and mental models of the business experts. This then supports collaboration because business experts and software developers are able to solve problems together as a result of their respective models being valid. Insights gained in either model are shared and knowledge is increased, leading to better problem solving and clearer communication between the business and development team.

The Challenges with Upfront Design

Historically, the capturing of requirements for software systems was seen as an activity that could occur long before coding was due to start. Business experts would talk to business analysts, who in turn would talk to architects, who would produce an analysis model based on all the information from the problem domain. This analysis model would then be handed over to the developers, along with wireframes and work flow diagrams, so they could build the system

As developers start to implement the analysis model in code, they often find a mismatch between the high-level artifacts produced by architects and the reality of building the system. However, at this stage there is often no feedback loop for developers to talk to the business and architects, so the analysis model can be updated and their input enacted. Instead, the developers diverge from the analysis model, and their implementation often overlooks important and descriptive domain terms and concepts that would have provided deeper insight and understanding of the domain.

As the development team further evolves away from the analysis model, it becomes less and less useful. Crucial insight into the model is lost as the development team focuses on abstracting technical concerns instead of business concepts. In the end the job gets done, but the code bears no reflection to the original analysis model. The business still believes the original analysis models are correct and is unaware of the alterations within the code model.

Figure 4.4 shows how the analysis and code models can diverge from each other if the development team is not involved in domain knowledge crunching.

images

FIGURE 4.4 The problems with upfront design.

The problem is revealed when later enhancements to the codebase are difficult to implement. The difficulties are due to the business experts and developers having different models of the business. The code doesn’t have a synergy with the business processes and is not rich in domain knowledge.

Team Modeling

DDD suggests a more collaborative method of capturing system requirements and understanding existing work flow. Emphasis is placed on the entire team, with business experts and architects (as long as they code) having discussions around the problem space. Discussions can include any documentation or legacy code that is related to the system in question. The idea behind the collaborative knowledge-crunching sessions is for the developers, testers, business analysts, architects, and business experts to work as a unified team. This enables the developers and testers to learn about the meaning behind domain terms, and understand complex logic in the problem area. It also enables business experts to experience the modeling techniques employed. With an understanding of modeling, business experts will themselves be able to model and validate designs with the development team.

The sharing of information enables business experts to contribute to the software design, and provides a deeper insight and understanding of the domain to the development team. After a period of time, developers and business experts will discover the relevant information to build an initial model of a problem domain. This initial model is put to the test by using domain scenarios: real problems of the domain to validate its usefulness. Modeling out loud, using the terms and language of the model, can also help to validate early designs.

The important aspect of modeling together is the constant feedback the development team gets from the business experts. This leads to the discovery of important concepts and allows the team to understand what is not important and can be excluded from the model. Breakthroughs in sessions are manifested as simple abstractions that clarify complex domain concepts and lead to a more expressive model.

The model is then expressed in code and the team, along with business experts, can gain fast feedback with early versions of software. Feedback in turn fuels deeper insight, which can be reflected in the code and analysis models, as highlighted in Figure 4.5.

images

FIGURE 4.5 The code model and the analysis model are kept in synergy.

During each iteration, the development team members may come across parts of the model that they thought were useful and could solve a problem but during implementation had to change. This knowledge is fed back to the business experts for clarification and to refine their own understanding of the problem domain. In this process, the code model and analysis model are one, and a change in one will result in a change to the other.

Figure 4.6 shows how the analysis and code model are in synergy and evolve as one during the creation of a product.

images

FIGURE 4.6 Team modeling.

Using a Ubiquitous Language to Bind the Analysis to the Code Model

The true value of following the Domain-Driven Design (DDD) philosophy is in the collaboration of developers and domain experts to produce a better understanding of the domain. The code that is written is just an artifact of that process, albeit an important one. To reach a better understanding, teams need to communicate effectively. It is the creation of the ubiquitous language (UL) that enables a deeper understanding that will live on after code is rewritten and replaced.

A UL enables teams to organize both the mental and the code model with ease. It achieves an unambiguous meaning because of the shared understanding that it brings to the teams. A UL also provides clarity and consistency in meaning. The language is ultimately expressed in code, but speech, sketch, and documentation are also important for creating the language. The language is constantly explored, verified, and refined with new insights and greater knowledge.

A Language Will Outlive Your Software

The usefulness of creating a UL has an impact that goes beyond its application to the current product under development. It helps define explicitly what the business does, it reveals deeper insights into the process and logic of the business, and it improves business communication.

The Language of the Business

I recently went curtain shopping with my wife. Pleated, hang length, interlining—these were all terms that meant something specific in the domain of curtain makers. Employees in the shop could spend hours describing what they wanted, but that could lead to ambiguity in meaning. But because the employees use terms in the domain of the curtain shop, conversations are kept short and concise, and everybody who understands the domain understands their meanings.

It’s the same with carpenters, financial traders, the military, and nearly every domain you can imagine. Each has terms and concepts that mean something very particular to them. A secret language enables complex topics to be covered in concise and meaningful dialogue without the need for confusing babble. It’s vital for a development team to understand and collaborate on this language, known as the ubiquitous language (UL). The UL’s terms and concepts are used when communicating with team members, including domain experts. They’re also used to name classes, methods, and namespaces in the codebase.

Translation between the Developers and the Business

The business language is a rich dialect with highly descriptive and insightful terminology. However, if the development team doesn’t engage with domain experts to fully understand the language and use it within the code implementation, much of its benefit is lost. Developers instead create their own language and set of abstractions for a problem domain. Without a shared model and UL, effective communication between the development team and domain experts is a challenge and requires some form of translation. Translation from domain concepts to technical concepts can be time consuming and error prone. Vital domain insights can be lost when the team implementing the code is using a different model than that of the domain expert. Furthermore, lengthy and convoluted communication is required to explain problems that the team faces in a software implementation that could be solved easily with a better understanding of the problem domain and a more efficient way of communicating.

Figure 4.7 shows how a different model in the minds of a developer can make communication with the domain expert problematic. In the code, the developer is focused on technical abstractions, design patterns, and design principles, whereas the domain expert is focused on business process and work flow.

images

FIGURE 4.7 Translation costs of the project.

Developers should think in domain terms and concepts, not technical terms, to avoid the need to translate from business jargon into technical jargon. If the development team makes a mistake when translating complex logic and work flow, the chance of creating a bug in code significantly increases.

Collaborating on a Ubiquitous Language

The rich language that the business uses to describe what it does is one ingredient of the UL. However, when creating a model of the problem domain and implementing it in code, you may need to create new concepts and terminology. The business may use jargon much in the same way that the IT community does, with some terms proving to be too generic. The development team and domain experts need to create new terms and explicitly define the meaning of existing terms to implement the model in code.

As teams are implementing the model in code, new concepts may appear, often highlighted by a collection on logic that needs to be named. These discovered terms need to be fed back to the domain experts for validation and clarification.

Not only must the development team learn the explicit terms and concepts from the business, but they must collaborate with the domain experts to define the assumed or implicit concepts that may not have terminology. These concepts must be named by the entire team and included in the shared UL. The team may also need to create terms for concepts that don’t exist in the problem domain but have been discovered and labeled during modeling in the software.

The team members must communicate with each other using the UL. The development team must use it in code, and the domain experts must use it when talking to the team. A shared language removes the need to translate from business speak into technical language and vice versa. It also removes the possibility of ambiguity and misinterpretation because everyone understands the meaning behind the concepts.

The UL should be clear and concise. Technical terms should be removed so they don’t distract from business concepts. Likewise, domain terms not relevant for the software under creation must not be allowed to cloud the shared language.

Carving Out a Language by Working with Concrete Examples

As mentioned in Chapter 2, “Distilling the Problem Domain,” to better understand the domain you’re in, it’s a good idea to take specific examples of domain behavior. Concrete examples of real scenarios help to cement processes and concepts within the domain. However, it’s important to reveal the intention of the business process and not the implementation. Talk only in business terms; don’t get technical.

In the following dialogue, a business user is describing the process of customers at an e-commerce site requesting a replacement for an order that wasn’t delivered:

When a customer doesn’t receive her goods, she can request a new order for free. She logs into her account and clicks on the I Have Not Received My Items button. If she has already been flagged as having received a free order, she can’t get another one without speaking to customer service. Otherwise, we will send her a free order and update the database to show that this customer has already claimed for a lost item. We will then contact the courier to see if we can claim back the cost of the lost order.

You will notice in the description that the business user is not focusing on the business process, but rather the implementation concerns. The following sentence gives no value or insight into the domain or business process:

She logs into her account and clicks on the I Have Not Received My Items button.

In the next sentence, the business user is already second-guessing how you will implement the business policy. Some experts may have experience with databases and may go as far as suggesting data schemas. Again, this gives the team no deep understanding of the domain:

If she has already been flagged as having received a free order, she can’t get another one without speaking to customer service.

From this set of requirements, a team not interested in the domain may simply implement what it is told and end up with a poor model that doesn’t reflect the concepts and policies of the domain. The impact of this could be a misunderstanding of what “flagging the customer” means; it may mean more than simply a tick in a database column and perhaps the catalyst for the start of a separate business work flow. Without understanding the domain and the intent of a feature, the developers won’t appreciate the repercussions of just implementing what they are told.

Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution

Training and collaboration will help business people focus on the process rather than the implementation and the problem space rather than the solution space. Next, the previous requirements statement has been rewritten using the language of the domain. It focuses on the business and its processes:

If you have not received an order, you can submit an undelivered order notification. If this is your first claim, a replacement order is created. If you have made a claim before, your claim case is opened and assigned to a customer service representative, who will investigate the claim. In all cases, a lost mail compensation case is opened and sent to the courier with details of the consignment that was undelivered.

In this description, you have discovered many important domain concepts that were missing before. The rewritten prose introduces some terms into the UL, and the terminology of the domain has been made crystal clear. In fact, the second description doesn’t even contain the customer concept; instead, it focuses only on terms that are directly related to the process.

Remember: domain experts have no, or limited, understanding of technical terminology. Keep examples focused on the business, and if domain experts are trying to help you by jumping to implementation details, just gently remind them to focus on the what and the why of a system and ask them to leave the how up to you.

Best Practices for Shaping the Language

The following best practices can help to shape your UL.

  • Ensure that you have linguistic consistency. If you are using a term in code that the domain expert doesn’t say, you need to check it with her. It could be that you have found a concept that was required, so it needs to be added to the UL and understood by the domain expert. Alternatively, maybe you misunderstood something that the domain expert said; therefore, you should rectify the code with the correct term.
  • Create a glossary of domain terms with the domain expert to avoid confusion and to help make concepts explicit.
  • Ensure that you use one word for a specific concept. Don’t let the domain expert or developers have two words for something because this can lead to confusion, or there might be two concepts with different contexts.
  • Stay away from overloaded terms like policy, service, or manager. Be explicit even if it means being wordy.
  • Don’t use terms that have a specific meaning in software development, such as design pattern names, because developers may assume its implementation rather than behavior.
  • Naming is very important. Validate your code design by speaking to your business users about classes. Would a business user understand “Query sent to the cache with, users matched using regex to determine if they get discount”. Does your code and concepts make sense when you say them aloud? If not ask your domain expert on how they would name concepts.
  • Name exceptions in terms of the UL.
  • Don’t use the name of a design pattern within your domain model. What does a decorator mean to a business user? Would they understand the role of a factory? Perhaps your business already has the concept of an adapter; the Gang of Four design pattern could confuse them.
  • The UL should be visible everywhere, from namespaces to classes, and from properties to method names. Use the language to drive the design of your code.
  • As you gain a deeper understanding of the domain you are working in, your UL will evolve. Refactor your code to embrace the evolution by using more intention-revealing method names. If you find a grouping of complex logic starting to form, talk through what the code is doing with your domain expert and see if you can define a domain concept for it. If you find one, separate the logical grouping of code into a specification or policy class.

How to Create Effective Domain Models

Rich domain models are built to satisfy complex problems, the best way to create effective domain models is to firstly focus on areas of the application that are important to the business. Ignore the parts of a system that simply manage data and where most of the operations are CRUD based. Instead look for the hard parts, the areas in the core domain that the business cares passionately about and often the parts that are key to making or saving money.

Don’t Let the Truth Get in the Way of a Good Model

A common misunderstanding is that a domain model should match reality; in fact, you should not look to model real life at all but rather model useful abstractions within the problem domain. Look for commonalities and variations within the problem domain. Understand which are likely to change and are considered complex. Use this information to build your model. It will be far more useful than identifying nouns and verbs based on the world of the problem domain. Most importantly model only what is needed to meet the need of the business case scenario.

A domain model is not a model of real life; it is a system of abstractions on reality, an interpretation that only includes aspects of the problem domain that are prevalent to solving specific business use cases. A domain model should exclude any irrelevant details of a domain that do not serve to solve problems. The London Tube map shown in Figure 4.8 was designed to solve a problem. It doesn’t reflect real life. It isn’t useful for calculating distances between landmarks in London, but it is useful for traveling on the underground. It’s simple and effective within the context that it was designed for.

images

FIGURE 4.8 London Tube map bearing little resemblance to the distance between stations.

Because it’s not concerned with modeling real life, the domain model cannot be deemed as being wrong or right. Rather, it should be viewed as useful or not for the given problem it is being used to solve.

Creating an effective domain model is fundamental to DDD. It is the artifact of knowledge crunching and sharing, design insight, and breakthroughs. Having a useful model that is rich in the UL is the key to meeting business objectives in the problem domain. Creating a useful domain model is hard and takes lots of exploration, experimentation, collaboration, and learning.

Model Only What Is Relevant

The domain model exists for one reason: to serve the application under development. Remember to be selective when creating your domain models; you don’t have to include everything. Businesses are big and complex with a lot going on. Trying to create that world within a single model would be at best foolish and at worst extremely time consuming and rather pointless. Needless to say, it would be a maintenance nightmare. If you are modeling a large system, break it down to more manageable chunks by clearly sectioning off parts of the model.

Try not to model real relationships; instead, define associations (meaningful connections) in terms of invariants and rules in the system. In real life, a customer has both a credit history and a contact e-mail address, but how often would you come across a rule requiring you to have a good credit history and an e-mail address starting with “A” to be able to purchase an item? Instead, group behavior and data to satisfy the needs of the problem domain rather than what you think might belong together. Remember that you are producing a model to fulfill the needs of a business use case (or set of business use cases), not trying to model real life.

To keep your domain model relevant and focused, you should constantly challenge the model you create against new scenarios and validate your understanding with domain experts. Remove any behavior that is no longer relevant to avoid noise.

Domain Models Are Temporarily Useful

A domain model needs to be constantly refined to continually be useful. A domain model is only ever temporarily useful for a given iteration and set of use cases. Future use cases or changes to the business may render the model useless. The domain model represents an implementation of the shared language that is applicable for only that moment in time. It is with this understanding that developers should not be too attached to an elegant model. They need to be willing to rip up and start again if the model becomes irrelevant.

Be Explicit with Terminology

Being able to communicate effectively is the most important skill for solving problems. A developer’s purpose is not to code; it’s to solve problems. That’s why it’s vital to talk to the business you are working for in a language without ambiguity or need of translation. By removing linguistic barriers, domain experts and the development team are free to collaborate, explore, and experiment with designs for a useful model. Technical implementations can then be expressed using the same UL, and any design insights can then be fed back to domain experts for validation without need for translation and loss of meaning.

Limit Your Abstractions

Introduce abstractions for commonality only, and even then try and avoid them. Abstractions come at a cost. It is far better to be explicit than worry about not repeating yourself as trying to tie loosely related concepts under a super class can cause problems with code maintenance.

An abstract class or an interface should represent an idea or a concept in your domain. It is really important to limit abstractions in your code base and only create them for concepts in your domain that have variations. Don’t seek to abstract every domain concern. If it’s not a variation of a concept then keep it concrete and only abstract if, and when, you create a variation of it. Remember it is always better to be explicit rather than hiding an important domain concept behind layers of needless abstraction.

So when should you abstract? Take the example of traveling to work. The abstract concept would be to commute whereas walking, taking the train, or driving is a variation of that concept; i.e., the concrete implementation. If there were no variation in traveling to work (i.e., we all drove) we would not need to introduce an abstract concept such as commuting.

Focus Your Code at the Right Level of Abstraction

An effective domain model should express the intent of the business use case by aiming code at the right level of abstraction. Readers should be able to quickly grasp domain concepts without having to drill down into the code to understand the implementation details.

Create abstractions at a high level; too many abstractions at a low level will cause a great amount of friction when you need to refactor your model to handle a new scenario or when you have a design breakthrough.

There is always a cost to introducing abstraction so we must be careful to apply it at the right level and to areas of code that will benefit from it. At a low level we should avoid abstraction and instead favor composition of behavior from explicit concrete objects. Abstraction creates a dependency between classes and more dependencies equate to higher code coupling.

Abstract Behavior Not Implementations

You shouldn’t have an abstraction that is specific for a particular problem; abstractions represent general concepts such as a IShippingNoteGenerator for an order processing application. Variations of this concept could be domestic and international due to the differences between paper work required. Don’t automatically abstract concepts that are related. Continuing with the fulfillment domain, don’t try and create a common abstraction for courier gateways; they don’t represent domain behavior, they are infrastructural concerns. Instead keep these implementations concrete, explicit, and out of the domain model. When we talk about domain concepts we are really talking about domain behavior. Create abstract classes or interfaces based on behavior; keep them small and focused. Ask yourself how much variation is there in domain behavior? Don’t force abstraction; use it only when it will help to express concepts clearer in you model.

Just as design patterns emerge when you refactor code so will domain concepts. When they do and you find variations of the concept then you can introduce abstractions in the form of interfaces or abstract classes. Also be mindful of premature refactoring. If you don’t know the domain well enough then you may not know the best way to refactor. Instead of painting yourself into a corner let the code grow for a few iterations then look to see natural patterns appear around related behavior. With this clarity you will be in a much better place to start to refactor and introduce abstractions.

Look at all of the abstractions in your system. What do your interfaces and base classes tell you about the domain of your application? They should reveal the major concepts in your system and not just be abstractions of each implementation.

Implement the Model in Code Early and Often

It is vitally important to test your design in code against domain scenarios to ensure your white board thinking can work as well as discovering any technical constraints that require an alteration or compromises to the model. Technical implementations will reveal any problems with the design and will help cement your understanding of a problem domain.

Don’t Stop at the First Good Idea

Only stop modelling when you have run out of ideas and not when you get the first good idea. Once you have a useful model start again. Challenge yourself to create a model in a different way, experiment with your thinking and design skills. Try to solve the problem with a completely different model. If you don’t get it right the first time, refactor to a better solution. Constantly refactor to your understanding of the problem domain to produce a more express model. Models will change with more knowledge.

Remember a model is only useful for a moment in time; don’t get attached to elegant designs. Rip up parts of your model that are no longer useful, and be willing to change when new use cases and scenarios are thrown at your design.

When to Apply Model-Driven Design

Simple problems don’t require complex solutions. You don’t need to create a UL for your entire application. Focus your efforts with domain experts on the complex or important core domain. For generic/supporting domains don’t waste your efforts, epically if there is no domain logic; doing so will frustrate your busy domain experts and leave them reluctant to help out with the complex areas of your application.

When you come across an area of complexity, you’re having trouble communicating with the stakeholder, or your team is working in part of the domain that you don’t have much experience with, this is the time to break out, model, and work on the UL.

Always challenge yourself and ask the questions, “Am I working within the core subdomain? Does this problem require a rich domain? Does the business care about this area of the application? Will it make a difference? Is it important to the business and do they have high expectations of it or do they just want it to work?”

If It’s Not Worth the Effort Don’t Try and Model It

If you have a particularly nasty and complex edge case that is in an area of the system that is not core then you should think about making it a manual process. Not handling edge cases and making them an explicit manual process instead can save valuable time and give you more resources to work on the core domain. Humans and manual processes are great at edge cases and can often make decisions based on data that would take a considerable amount of time to replicate.

Focus on the Core Domain

The core domain of your application is why it is being built rather than bought. It is what your stakeholders are most passionate about, and where you can have interesting conversations and valuable knowledge-crunching sessions. This is the area where your UL gives you the most value, and demands your focus. Try not to create a rich language for your entire domain because many of your supporting and generic domains do not require one and are a waste of effort. Focus your efforts on what gives you value. Try not to create a UL for everything. Areas and subdomains that are not complex will not benefit from a UL, so don’t spread yourself too thin. A core domain is small; focus on it. Creating a UL is costly.

The Salient Points

  • The domain is the reality of the problem. The domain model is a set of abstractions based on a projection of the domain designed to handle specific business use cases.
  • A model is represented as an analysis model and a code model. They are one and the same.
  • A domain model exists as an analysis model and a code model. A Model-Driven Design binds the analysis model and a code model through the use of the shared language.
  • An analysis model is only useful if it stays in synergy with the code model.
  • If you are shaping the analysis or code models, you have to be hands-on and contribute to code. There is a place for architects, but they must be coders as well.
  • Code is the primary form of expression of the model and needs to be bound using the ubiquitous language.
  • The process of developing a UL is the most important of Domain-Driven Design (DDD) because it enables communication and learning.
  • Domain jargon must be explicitly defined to ensure accuracy in meaning because the terminology used in communication is baked into the code implementation.
  • Implicit ideas in the domain that the team needs to understand are made explicit and given names that form the shared ubiquitous language.
  • Domains are full of specialist terms and language that describe complex concepts in a clean, concise manner.
  • Feature stories and scenarios can help you understand the behavior of a system, but a domain expert will help you build a model that can support the specified behavior.
  • The ubiquitous language should be used in tests, namespaces, class names, and methods.
  • It’s important to care about the conversation; a ubiquitous language is about collaboration and not the development team just adopting the language of the business.
  • Use domain scenarios to prove the usefulness of the model and to validate the team’s understanding of the domain.
  • Only apply Model-Driven Design and create a UL for a core domain that will make a difference. Don’t apply these practices to the entire application.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.216.175