Another easy concept, that for some reason, took me a while to understand – invariants.
An (object oriented) software contains objects (of a certain domain), and each object has a state. Depending on the business domain / the business rules of the program at hand, there could be rules that must be enforced, guaranteed by the programmer just like in my little traffic light example, I defined a rule saying there can never be more than one light switched on concurrently. In the “real world”, imagine the chaos that would result from the red and the green light being switched on at the same time.
Invariants are like business rules on a number of the object’s attributes. Like all the lights in our traffic light example – when you “turn on” one light, you must ensure that the other two lights are turned off. In a multi-threaded environment, if your object is used concurrently, you must ensure that invariants are updated “atomically”, which means you must ensure (for example by synchronization), that the internal update of more than one attribute (forming the “invariant”) cannot be interrupted by other threads – because otherwise it would be possible that our “invariant” rule to be violated by a thread reading from an object that is just in the middle of an unfinished “update process”.
To simplify defining atomic operations on our invariants, it might be wise to encapsulate the invariant-related attributes (internal Objects or primitive values) in a specific “wrapper” class, which only provides synchronized access to our invariants (or is designed as an immutable object, etc.). This way, we pin point the atomicity at the smallest possible scope, which makes our domain easier to understand and might improve its performance.