There are other ways to introduce business rules in the model than using state machines and guards. You can use Constraints.
The model already has several implicit constraints from the cardinalities of the association ends. If you have cardinality 1..4 and you have zero objects in that relation – then you have a broken constraint.
Define Constraints
You may also define your own constraints:
You can choose if a broken constraint (a constraint that evaluates to false) should be treated as Information, Warning, or an Error to the user.
Delete Constraints
You can also define the constraint as being a delete constraint only:
This way, you have explained at the model level that the domain does not consider it acceptable to delete a Car-object as long as we have the deposit unless it is in state Scrapped.
The delete constraints will be checked when Deleted by MDriven. As a result, the Delete operator is executed on the class.
Other things that are checked when the Delete operator is run are the Business Delete Rules that exist on all association endpoints:
As modelers, we should decide the best rule for each association end. In this case, is it acceptable to delete a Brand if Cars are left in the AllCarsOfThisBrand association? No, I think not. I am setting it to “MustBeEmpty.”
The association is in the other direction on the other hand.
I set that to “NeedNotBeEmptyNoWarning” – because deleting a car object is okay even if it has a brand.
Constraints Evaluation in OCL
If you want to evaluate constraints in OCL, use OCLOperators constraints, for example.
Usage of Constraints
Constraints automatically show up in ViewModels - but you may opt them out on a per-ViewModel level:
You can also access Constraints and their "brokenness" via OCL Operators brokenConstraints and Constraints:
The MDriven Book - Next Chapter: The ViewModel
See also: OCLOperators_constraints