71 lines
4.3 KiB
Text
71 lines
4.3 KiB
Text
Singletons and Dependency Handling
|
|
==================================
|
|
:Date: 2018
|
|
:Toc:
|
|
|
|
WARNING: [red]#under construction# +
|
|
There is a rather complete page ``DependencyFactory'' in the TiddlyWiki,
|
|
which should be integrated here
|
|
|
|
We encounter _dependencies as an issue at implementation level:_ In order to deal with some task at hand,
|
|
sometimes we need to arrange matters way beyond the scope of that task. We could just thoughtlessly reach out and
|
|
settle those extraneous concerns -- yet this kind of pragmatism has a price tag: we are now mutually dependent
|
|
with internals of some other part of the system we do not even care much about. A more prudent choice would be
|
|
to let ``that other part'' provide a service for us, focussed to what we actually need right here to get _our_
|
|
work done. In essence, we create a dependency to resolve issues of coupling and to reduce complexity
|
|
(»divide et impera«).
|
|
|
|
Unfortunately this solution created a new problem: how do we get at our dependencies? We can not just step ahead
|
|
and create them or manage them, because then we'd be ``back to square one''. Rather someone else has to care.
|
|
Someone _needs to connect us with those dependencies,_ so we can use them. This is a special meta-service known
|
|
as _Dependency Injection_. A dedicated part of the application wires all other components, so each component
|
|
can focus on its specific concern and abstract away everything else. Dependency Injection can be seen as
|
|
application of the principle »Inversion Of Control«: each part is sovereign within its own realm, but becomes
|
|
a client (asks for help) for anything beyond that.
|
|
|
|
|
|
Requirements
|
|
------------
|
|
_tbw_
|
|
|
|
Configuration
|
|
~~~~~~~~~~~~~
|
|
_tbw_
|
|
|
|
Performance
|
|
~~~~~~~~~~~
|
|
_tbw_
|
|
|
|
|
|
Architecture
|
|
------------
|
|
Dependency management does not define the architecture, nor can it solve architecture problems.
|
|
Rather, its purpose is to _enact_ the architecture. A dependency is something we need in order to perform
|
|
the task at hand, yet essence of a dependency lies outside the scope and relates to concerns beyond and theme
|
|
of this actual task. A naïve functional approach -- pass everything you need as argument -- would be as harmful
|
|
as thoughtlessly manipulating some off-site data to fit current needs. The local function would be splendid,
|
|
strict and referentially transparent -- yet anyone using it would be infected with issues of tangling and
|
|
tight coupling. As remedy, a _global context_ can be introduced, which works well as long as this global
|
|
context does not exhibit any other state than ``being available''. The root of those problems however
|
|
lies in the drive to conceive matters simpler as they are.
|
|
|
|
- collaboration typically leads to indirect mutual dependency.
|
|
We can only define precisely _what is required locally,_ and then _pull our requirements_ on demand.
|
|
- a given local action can be part of a process, or a conversation or interaction chain, which in turn
|
|
might originate from various, quite distinct contexts. At _that level,_ we might find a simpler structure
|
|
to hinge questions of lifecycle on.
|
|
|
|
In Lumiera we encounter both these kinds of circumstances. On a global level, we have a simple and well defined
|
|
order of dependencies, cast into link:{ldoc}/design/architecture/Subsystems.html[Subsystem relations].
|
|
We know e.g. that mutating changes to the session can originate from scripts or from UI interactions.
|
|
It suffices thus, when the _leading subsystem_ (the UI or the script runner) refrains from emitting any further
|
|
external activities, _prior_ to reaching that point in the lifecycle where everything is ``basically set''.
|
|
Yet however self evident this insight might be, it yields some unsettling and challenging consequences:
|
|
The UI _must not assume_ the presence of specific data structures within the lower layers, nor is it allowed to
|
|
``pull'' session contents while starting up. Rather the UI-Layer is bound to bootstrap itself into completely
|
|
usable and operative state, without the ability to attach anything onto existing tangible content structures.
|
|
This runs completely counter common practice of UI programming, where it is customary to wire most of the
|
|
application internals somehow directly below the UI ``shell''. Rather, in Lumiera the UI must be conceived
|
|
as a _collection of services_ -- and when running, a _population request_ can be issued to fill the prepared
|
|
UI framework with content. This is Inversion-of-Control at work.
|
|
|