Context Map

The context map is the most important element of CML, implementing the DDD Context Map pattern. A context map contains bounded contexts and defines their relationships.

Syntax

The following CML code snippet illustrates an example for a context map, according to our customized DDD Sample. With the contains keyword you add a bounded context to the map.

ContextMap {
  type = SYSTEM_LANDSCAPE
  state = AS_IS

  contains CargoBookingContext
  contains VoyagePlanningContext
  contains LocationContext
	
  CargoBookingContext [SK]<->[SK] VoyagePlanningContext
}

Alternatively, you can use only one contains keyword and list all bounded contexts comma-separated:

ContextMap DDDSampleContextMap {
  type = SYSTEM_LANDSCAPE
  state = AS_IS

  contains CargoBookingContext, VoyagePlanningContext, LocationContext

  CargoBookingContext [SK]<->[SK] VoyagePlanningContext
}

As you can see in the example above, it is also possible to name a context map (optional).

A context map can be of one of the following types:

  • SYSTEM_LANDSCAPE
  • ORGANIZATIONAL

While a SYSTEM_LANDSCAPE represents the typical context map with the relationships between bounded contexts, an ORGANIZATIONAL map (or ‘team map’) illustrates the relationships between teams. An example for such a team map can be found here.

The state attribute accepts the following two values, expressing if the given context map represents the current or the desired state:

  • AS_IS
  • TO_BE

Relationships

According to our semantic model, we support the following symmetric relationships:

  • Partnership
  • Shared Kernel

The asymmetric relationships are represented by the following two types:

  • Upstream-Downstream (generic)
  • Customer-Supplier (a special form of an Upstream-Downstream relationship)
Note: A customer-supplier relationship is an upstream-downstream relationship where the downstream priorities factor into upstream planning. The upstream team may succeed interdependently of the fate of the downstream team and therefore the needs of the downstream have to be addressed by the upstream. They interact as customer and supplier. A generic upstream-downstream relationship is not necessarily a customer-supplier relationship! (in CML you have to express this explicitely)

The syntax for upstream-downstream relationships is explained below. For the syntax of customer-supplier relationships please visit Customer/Supplier.

For the symmetric relationships and their syntax please visit Partnership and Shared Kernel.

Upstream-Downstream relationships can be defined with three different syntax variants, all illustrated with the examples below:

CargoBookingContext [D]<-[U] LocationContext
LocationContext [U]->[D] CargoBookingContext
LocationContext Upstream-Downstream CargoBookingContext
CargoBookingContext Downstream-Upstream LocationContext

All of the four variants are semantically equivalent. Note that the arrow -> always points from the upstream to the downstream and thus, expresses the influence flow (the upstream has an influence on the downstream, but the downstream has no influence on the upstream).

The syntax with the arrows and the abbreviations further allows to place the brackets with the upstream [U] / downstream [D] and relationship role patterns specification flexible in front or after the Bounded Context name:

CargoBookingContext [D]<-[U] LocationContext
[D]CargoBookingContext <- [U]LocationContext
CargoBookingContext[D] <- LocationContext[U]
[D]CargoBookingContext <- LocationContext[U]

With a colon at the end, you can give every relationship a name:

CargoBookingContext [D]<-[U] LocationContext : CargoLocationRelationship

Note: The following quick upstream/downstream syntax without brackets can be used as well. It denotes a common upstream/downstream relationship without any roles. However, with this syntax it is maybe not explicitly clear for a reader that you declare an upstream/downstream and not a customer/supplier relationship.

CargoBookingContext <- LocationContext
LocationContext -> CargoBookingContext

Relationship Roles

Within the brackets you can further specify the relationship roles such as Open Host Service (OHS) or Anti-Corruption Layer (ACL). Roles must always be specified behind the U (upstream) and the D (downstream).

VoyagePlanningContext [D,ACL]->[U,OHS,PL] LocationContext

If you use the Upstream-Downstream or Downstream-Upstream keywords the roles are declared equivalently, but without the D and U: (note that it does not matter if you write a whitespace before or after the brackets, or both)

VoyagePlanningContext[ACL] Downstream-Upstream [OHS,PL]LocationContext

Upstream roles are given by the Open Host Service (OHS) and Published Language (PL) patterns. Downstream roles are Conformist (CF) and Anticorruption Layer (ACL).

Relationship Attributes

By using brackets {}, you can specify further attributes for a relationship. Currently supported attributes are:

  • implementationTechnology
  • downstreamRights
  • exposedAggregates

Implementation Technology

Within the body of the declaration it is possible to specify the implementation technology used to realize this relationship:

VoyagePlanningContext [D,ACL]->[U,OHS,PL] LocationContext {
    implementationTechnology = "RESTful HTTP"
}

Downstream Governance Rights

With the attribute downstreamRights you can define which governance rights, and therefore which influence, the downstream has on the upstream within the specified relationship:

VoyagePlanningContext [D,ACL]->[U,OHS,PL] LocationContext {
    implementationTechnology = "RESTful HTTP"
    downstreamRights = VETO_RIGHT
}

The possible governance rights values are:

  • INFLUENCER
  • OPINION_LEADER
  • VETO_RIGHT
  • DECISION_MAKER
  • MONOPOLIST

Exposed Aggregates

The exposedAggregates attribute offers the possibility to declare which Aggregates of the upstream bounded context are exposed in order to realize this relationship. The attribute takes a comma separated list of references to aggregates. The referenced aggregates must be part of the upstream context of the relationship.

VoyagePlanningContext [D,ACL]->[U,OHS,PL] LocationContext {
    implementationTechnology = "RESTful HTTP"
    downstreamRights = VETO_RIGHT
    exposedAggregates = Customers, Addresses
}

Special Case: Customer/Supplier

For the Customer-Supplier relationship, which is a special form of Upstream-Downstream relationship, please visit Customer-Supplier.

Semantic Rules

Note that semantic rules (validators) exist for context maps within CML. This means that not every combination of patterns and concepts is allowed, even if it would be syntactically correct. The following rules apply to a context map:

  • A bounded context which is not part of the context map (referenced with the contains keyword), can not be referenced from a relationship rule within that context map.
  • A bounded context of the type TEAM can not be contained in a context map if the context map type is SYSTEM_LANDSCAPE.
  • If the context map type of a context map is ORGANIZATIONAL, every bounded context added to the context map (with the contains keyword) has to be of the type TEAM.

For a summary of all semantic rules and further justifications, please consult Language Semantics.