Rules can be found everywhere, at every time along application life-cycle. Moreover, they often appear at the very beginning, when requirements are not structured. Then, rules may describe how activities are to be executed or objects processed despite distinctions still blurred and identities unaccounted for. Hence, the priority is to clarify their nature: passive or active, persistent or functional, applied to symbolic computation or actual control.
Hence, the first thing to do is to identify their footprint, for conditions, consequences or both:
- Rules made only of conditions are used to enforce the consistency of persistent representations (integrity constraints) or activity execution (preconditions).
- Rules made only of consequences are functions used to compute the value of features, trigger actions, or maintain the consistency of persistent representations (post-conditions).
- Rules made of both conditions and consequences are used to set the path of objects processing or processes execution.
Since rules can apply simultaneously to actual and symbolic objects and activities, they may have a significant impact on architectural constraints. Yet, on the other hand, they are obviously the most pliable and volatile components of business requirements and therefore should be easily modifiable; in other words, set within a layered approach of traceability, rules management should bypass platform independent models and directly target platform specific ones.
If system architects were to decide, symbolic and actual rules should be set independently. Unfortunately that’s not always the case and, in order to manage this conundrum, logic operators should be used to decompose rules with heterogeneous footprints into homogenous elements.
First, it is necessary to separate consequences that may affect actual objects or processes from symbolic ones, whose impact can be limited to symbolic representations.
Then, the scope of conditions and consequences should be layered depending on their footprint on architectures:
- Leafs will contain expressions targeting single features whose processing can be performed locally.
- Then one will find expressions that can be evaluated (or executed) locally by a single object or activity.
- Conditions targeting collections should be set one level up.
- Then one will find combined expressions whose footprint stand across domains, but remain within a single location.
- Finally the root will contain expressions with their scope distributed across different locations.
As far as architecture is concerned, local rules can be ignored since they can be managed by persistency or execution units without calling on system resources. The main challenge is therefore to distinguish between:
- Rules targeting persistency units, from those targeting execution units.
- Constraints, which are activated backward from a known persistency or execution unit, and full rules, whose forward consequences cannot be known upfront.
From an architectural perspective, footprints and modus operandi are the critical factor to be considered, hence, the next step should be to disentangle the rules in order to get homogeneous clauses. For that purpose, it may help to characterize the semantics of business rules using the classical logic categories:
- Deontic rules are meant to describe necessary conditions. Used for system modelling, that means conditions to be verified by business contexts independently of symbolic representations. Those must be enforced if system objects are to represent business contexts.
- Alethic (aka modal) rules describe possible, necessary or contingent conditions. Used for system modelling, those conditions may be directly applied to symbolic representations.
- Temporal rules describe conditions whose truth value is time-related. Those rules cannot be used for system modelling without taking into account the way symbolic representations take heed of external events.
As it happens, and not by chance, the distinction between deontic and alethic rules coincides with the one between business and functional requirements, the former describing actual constraints, the latter specifying how the system should support them. Hence, that provides a sound framework for requirements analysis, with the classification of rules congruent with problem spaces ‘business requirements vs functional ones) and architecture layers. That should be the rationale behind the definition of rule patterns.
Access to scythed chariots can be qualified at different levels, each with specific architectural consequences.
- Constraint on persistent representations: reservations of scythed chariots are only for officers.
- Constraint on processing: Before checking out a scythed chariot one must check the military status of the driver.
- Trigger on process: when driver’s military status doesn’t authorize scythed chariots, remove the scythes.
- Trigger on update: When a returned chariot is broken his status is to be reset to “unfit”.