Splits an aggregate which contains multiple entities and produces one aggregate per entity.
On the level of entities we typically try to group attributes or nanoentities in the terminology of ServiceCutter together, which belong to the same identity and share a common lifecycle. Thereby we aim to reduce the coupling between the entities and increase the cohesion within the entities.
- See also: Coupling criterion Identity and Lifecycle Commonality of ServiceCutter.
The same approach can be applied on the aggregate level. The aggregates within one bounded context shall be structured in a way which reduces coupling between the aggregates and increases the cohesion within them.
As your bounded context develops you may face the problem that an aggregate contains entities which exhibit an unsatisfying cohesiveness. In such a case you may want to split your aggregate into multiple aggregates in order to improve coupling and cohesion.
This Architectural Refactoring (AR) splits an aggregate and creates one aggregate for each entity. This AR can be applied when the entities within an aggregate exhibit unsatisfying cohesiveness and you decide to create multiple aggregates for the single entities.
Inverse AR's:
- The input aggregate must contain at least two entities.
- The aggregate which shall be split.
- Multiple aggregates which contain one entity each.
- All entities become aggregate roots within their own aggregates.
The following two CML snippets show an example input and output illustrating how this AR works.
The following bounded context contains one aggregate with two entities:
BoundedContext CustomerManagementContext {
type = FEATURE
domainVisionStatement = "The customer management context is responsible for managing all the data of the insurance companies customers."
implementationTechnology = "Java, JEE Application"
responsibilities = "Customers, Addresses"
/* With a Right-Click on the 'Customers' aggregate you can call the 'Split Aggregate by Entities' refactoring in the
* 'Context Mapper: Refactor' context menu. The refactoring will create a new aggregate and move one of the two entities
* to the new aggregate (see the result in the 'split-aggregate-by-entities-output-example.cml' file).
*/
Aggregate Customers {
Entity Customer {
aggregateRoot
String firstname
String lastname
- List<Address> addresses
}
Entity Address {
String street
int postalCode
String city
}
}
}
Applying the AR Split Aggregate by Entities produces two aggregates, one for each entity:
BoundedContext CustomerManagementContext {
domainVisionStatement = "The customer management context is responsible for managing all the data of the insurance companies customers."
responsibilities = "Customers, Addresses" implementationTechnology = "Java, JEE Application"
Aggregate Customers {
Entity Address {
aggregateRoot
String street
int postalCode
String city
}
}
/* The newly created aggregate after applying 'Split Aggregate by Entities' on the aggregate in the input file
* 'example-input.cml'.
*
* Note that the refactoring does not produce meaningful aggregate names. You can use the 'Rename Element'
* refactoring (SHIFT-ALT-R) to rename the new aggregate.
*/
Aggregate NewAggregate1 {
Entity Customer {
aggregateRoot
String firstname
String lastname
- List<Address> addresses
}
}
}
- Example input source: example-input.cml
- Example output source: example-output.cml