Wednesday, August 25, 2010

ALM Practices Part 11: Modeling the business domain using Domain Models

What is it?A domain model is typically depicted by a UML class diagram in which the classes and associations represent the business concepts and the relationships between them. Although you can use a piece of paper to draw up a domain model, in most cases a UML case tool is better suited for that. Business concepts such as orders, customers or contracts are represented by classes stereotyped as entity. Associations are used to illustrate the roles which that entity fulfills in in the relationship with other entities. An example of a domain model representing a recipe registration application might look like this: Why would you do it?

Because a domain model centralizes the concepts and behavior of the business domain at one place

Because while creating it, you'll run into many new important questions on both the static and dynamic aspects of the domain, including constraints, relationships, the business process, roles and responsibilities

Because it can be used to verify that the developers and other team members have the same view on the domain as the business people have.

What’s the minimum you need to do?

You should clearly communicate that the domain model should not be confused with a data model. It does not imply anything about the database schema and should not contain specific decisions or changes because of that database.

Make sure all entities, association roles, attributes, operations and other documentation comply with the Ubiquitous Language.

Write in your native language, unless company policy says otherwise.

Avoid bidirectional associations. It makes understanding the life cycle of related entities more difficult and introduces technical complexity that ripples throughout the entire system. I also found that bidirectional associations reduces the obviousness of the user interface, because a bidirectional relationships clouds the parent-child obviousness.

Always use directional associations. Base those on the conceptional relationship between the entities, not on the way you intend to query the domain for presentation purposes.

Always add roles to your associations. They may seem obvious, but by thinking about the role, you may find misinterpretations or an opportunity to get more insights in its purpose.

Don't specify a multiplicity of 1, but always specify the others explicitly.

Use a composite association when the child's lifecycle is dictated by the parent (like the Recipe-Ingredient association).

Don't include any technical terms or .NET-specific types such as string or integer. Use text, number, money or another type from the Ubiquitous Language instead.

Make sure that the individual class models are small and do not show more than what the model is intended for.

If an entity has a status attribute, carefully consider what impact each status has on the editability and associations of that entity. If these constraint become very complex, consider modeling the State Pattern or choose a design in which every state is represented by a dedicated subclass of the entity.

Do not include mutual exclusive associations. If you need these, your entity is probably representing multiple conflicting concepts and should be split up in multiple entities. Again, if these are related to a status attribute, see previous remark.

What’s the usual thing to do?

Group related entities that change together, have a dependent lifecycle or form a conceptual whole into a so-called aggregate and choose one entity as the entity that controls access to the others. This is called the aggregate root.

My rule of thumb for finding the right aggregate roots is to create a diagram that only contains the aggregate roots. That diagram should include the most important concepts of your domain and clearly illustrate its dependencies.

Include detailed constraints on the maximum length of text attributes, ranges of numbers and dates.

If such constraints tend to repeat itself for the same kind of data (e.g. an email address, ISBN number, credit card number or currency), consider introducing new classes representing domain-specific primitives with the associated constraints. Stereotype these as a value object and use them instead of primitive types. For instance, the above domain model relies on the following value objects.

If you find that the same set of entities have completely different meanings and dynamics depending on the department or organizational unit you ask, and you don't see a chance to get them aligned, you may need to introduce different domain models per organizational unit. This practice is often referred to as having more than one bounded context. In other words, different organizational units require different interpretations of the same domain concepts.