Understand Constructors
Understand Constructors Deep Dive
Any software development process carries inside impressive amount of code that deals just with one thing: creating new objects.
We create from simple to complex object graphs. During this process, once the system starts to enlarge, we face with the necessity to structure new objects’ creation. Here come “creators” constructions (whose only purpose is to ensure that the object graph is constructed as it should be) for facilitating this goal. However, the focus of this article is on what we create, rather than on how. Further we’ll refer to instance constructors.
What Does It Mean to Create an Object?
To decipher, no matter how it is performed, it always ends in a call of class’s constructor.
Every Object Must Be Consistent
Constructor’s purpose is to create new object.
Existential Consistency Principle
When digging into object’s construction to its basis, the only reason for it to exist is to construct a valid consistent object.
Causes and Consequences of Consistency
In case Existential Consistency Principle for the object is violated, the result is a brand new object which is in kind of “incomplete state” inside a concrete domain context of application design. Next, the only approach that would be followed is to trigger additional calls to bring the newly created object up to a “reasonable state”. Having and working with an incomplete object is equivalent to waiting for the right moment to fail. Objects must ensure the consistency of system’s context and carry valid state. If any mandatory characteristic of object’s consistency is not met at the time of object creation, the constructor is responsible to check this and obliged to fail. If constructor had succeeded, that means that newly created object satisfies all object’s protocol characteristics inside a given domain context in order to exist.
Consistency with default and parameterized constructors
Both constructor types must provide consistent objects. Parameterless constructor must provide consistent object as default rule, and constructor with parameters must force the caller to make any required preparation before calling the constructor and creating the object.
Actors and their roles
-
Caller of the constructor must prepare the objects that are requested by the constructor in advance.
-
Class’s constructor has full right to say something about the call that was issued on it from the caller.
-
Consumer, on the other hand, has an object and is free to use it.
Object Consistency and Validation
To ensure consistency you should place some checks, and to ensure validation you’ll have checks.
Key difference between object consistency and validation:
- Object consistency deals with existential prerequisites for the object to live, to exist.
- Validation deals with an already existing object and is bound to some concrete context, like some custom action that you want to apply on the object.
Constructors deal with object consistency, not with validation.
Incomplete Objects from Consistency Perspective
It may be argued on the approach and theory that advocates for incomplete information in objects and further techniques of handling inconsistency. While for sure, it has the right to live, the reason not to fall into this trap and avoid it, is the downside that from its very beginning arises when going this way: the possibility for a fail at an unexpected moment. Failure will be triggered on object from the caller, that did not supply accurately some mandatory consistency characteristic, which also wasn’t ensured by the constructor itself (we assumed to allow incomplete object existence). In other words, when the caller doesn’t do his part of the job to ensure complete consistency for the object, this incomplete object is placed on a queue, that only waits for the “right scenario” to fail.
Temporal Inconsistency Allowed Inside Single Process Creation
On other hand, when creating consistent objects, in some cases it is impossible to avoid completely the existence of incomplete objects. For example, let’s take a simple builder approach to create composite object A that consists of objects B and C. Assuming B and C are consistent, at the moment that B was assigned to A, and C wasn’t assigned yet, we have A as temporary incomplete with inconsistent state. The context given in this example is bound to a single process of creation. During it, we admit temporary inconsistency. This should be very clear and represents the key difference compared with the situation when we operate in multiple contexts with an inconsistent object A (just B was assigned), and getting at a later moment in some third or fourth context the consistency for A by assigning the C object to it.
Construct Consistent Complex Object
The technique to avoid inconsistency for complex graph object, is to split it in smaller objects, that, at any given moment are consistent. This way, we have to deal just with consistent thin objects that will compose at some future step the main consistent complex graph object we’ll operate on in specific context.
By ensuring consistency for every single object, automatically is ensured the consistency for any complex object graph, and for the whole developed system itself.
References
1 December 2018