TL;DR All systems (according to systems theory - that means computer software, but also board game, biotope or set of objects that are subjects to the basic law of physics) have some underlying "rules of the game" as a foundation - these invariants are used to derive more specific scenarios / cases. Trying to model the system w/o learning these invariants leads to wrong understanding & shaky foundations. What is more - trying to reverse engineer them is a huge effort w/o guaranteed success.
Some time ago, during a long discussion regarding different aspects of design & modeling, someone has come up with an interesting (yet daring) statement:
Do you know why detailed functional requirements' specifications based on User Story format are suboptimal? Because they focus only on positive conditions & scenarios, while in fact these are the less important part of the problem.
This sounded reasonable, but our discussion got skewed towards something else, so even if this statement somehow resonated with me, I didn't give it much thought until recently.
What has changed then?
Real-life experience gained in a new environment (with people who have completely different approach to design, decomposing business-related problems & abstract thinking in general) has taught me to appreciate value provided by so-called Domain Invariants.
What are Domain Invariants?
Domain invariants are the policies and conditions that are always met for the Domain in particular Context. Constraints, axioms, key characteristics that together build up the paradigm of particular Context. The rules of the game. They mainly tell you about:
- what is not possible or prohibited in the Context (e.g. "until User is validated, it can't make any kind of purchase")
- what are the formulas or definitions that always do apply (e.g. "your portfolio always consists of: your clients, your team's clients & prospects in your geo area")
- fundamental laws of your business reality (e.g. "requested application's content is ineffective, until request is concluded", "there can be max. one annex to the contract in progress at any moment")
In fact, examples above are NOT proper Domain Invariants YET, as they don't cover proper reasoning: WHAT is the reason for particular invariant? WHY does this constraint apply?
Hmm, that just sounds like a different name for Business Validation Rules, right or no?
Close, but no.
- The most intuitive difference is actually a minor one -> validation is by convention applied over object (model) that has already been modified (but its state is not verified yet), while invariant guard this object (model) from being modified in a way that contradicts the invariants.
- By far more important difference is purely conceptual -> Domain Invariants do not correspond to business logic code containers (methods / functions / procedures / smart constructors) - they can be represented with type system, aspects, declarative attribute, access control modifiers, object / record relations, virtually any tool of language expression.
Rules of the game
But what's the exact difference between the specification of requirements for particular User Story and relying on Domain Invariants? Isn't it purely academic? Is this blog post just about labels & terminology?
Good question (bah, what else to expect - I'm asking myself, aren't I? ;P), fortunately the difference is quite clear:
- Requirement specified in a form of User Story is a single ("random") case (/ "instance"), a snapshot of a chunk of reality built on several, interwoven invariants - rules that determine this context are not clear, you need to RECREATE (/ REVERSE ENGINEER) them to fully understand the Context & make sure you implement the Requirement properly
- Domain Invariant is something that determines how this particular business operates in general -> it impacts plenty of scenarios, sometimes in unobvious way (when several invariants mix to one, joint resultant); changes in business environment usually focus on (are about) Domain Invariants (which can of course have a effect on plenty of scenarios)
Example? Sure thing.
Gravity determines how things move. So does friction, or let's put it more general - laws of dynamics. Trying to put these all aside & describe particular behaviors (soap sliding down on wet surface, feather falling down, rubber ball bouncing of the wall, cannonball shot at the angle, etc.) in separation, based just on empiric observations, without expressing clearly what defines, formulates & constraints this behaviors not only strips such models out of real knowledge, but also eliminates possibility of building "the big picture", "approximating" (or just - figuring out) some non-obvious scenarios (wet feather shot at the angle ;P).
That's why building application without well-shaped model of business it's supposed to aid/power reminds me trying to learn a complex board game (like Star Trader, Pandemic, Galaxy Trucker or Samurai Spirit) by observing individual moves (& their effects) only.
It is possible, but it takes a lot of time (which can be frustrating itself ...), there's high chance of misunderstanding some rules (e.g. missing some conditional rules, not being able to decompose composite interactions into atomic ones) & what may be in fact the most important - if you have already built some understanding based on wrong assumptions, once one of them (these assumptions) dissipates, what was already relying on them collapses like a house of cards.