At its core, an interactive application just does this:
- show data changing over time
- read controls that affect how data changes
Sri's Data Layers
The elements in this table are just for the pure data manipulated by the app, independent of any data structures related to the way this data is presented visually or converted into reports
DATA SRC
The true source of data, in its most normalized form. This lives in a database somewhere, with access carefully managed to prevent corruption.
DATA0
A straight copy of DATA SRC
. This is what is loaded into the interactive for local manipulation. I like this to be as close to the original form as possible for ease of debugging. I call the module that manages this a "datacore".
DDATA1
"Derived Data" that creates new structures around DATA
that convert the original data format into something easier for your code to use directly. Examples are lookup tables, filtered lists. This derived data structures are created when DATA0 is created, so it is part of datacore.
Up to now, these are all pure data that have not been adapted for use by a particular application need. These sets of data all correspond to the DATA API that is appropriate for a data service module.
From the pure data we create all sorts of glue data that we need to feed or cross reference to other code.
DDATA2
These are new data objects that are created based on values of DDATA1
, perhaps from multiple combined sources, creating a composite object that is still pure data. If either DATA or DDATA1 update, then DDATA2 must also update. This data may generated by a subscriber to datacore, creating specialized structures as needed as another type of datacore.
DDATA3
These are structure adapted for specific library APIs and used by that code. For example, your pure data source may contain a list of entity objects. Your GUI has to have a copy of that that it can filter and reorder, which then is converted into API-specific data structures for library calls. This glue data has to be converted to-and-from data defined in datacore.
GUI Ramifications
A GUI makes use of all these layers, because it needs:
- data to process, after conversion into sprites, html elements, etc
- derived data which are the intermediate data structures used for GUI-related library use
- events to handle, which are fired asynchronously for one of many sources and handled
- visualization of data, which requires derivative data tailored for view components
- state for read/write component data, component state, and application state
- operations the non-GUI code that does the application work, results in an update of some kind
I try to model each of these layers as distinct from each other as possible using one-way binding.
Binding Notes
INITIAL DATA SERVICE INIT
DATA0 --> DDATA1
DDATA1 --> DDATA2
APP DERIVED DATA
DDATA0 --> APPCORE (DDATA3)
DDATA1 --> APPCORE (DDATA3)
DDATA2 --> APPCORE (DDATA3)
APP DRAW DERIVED DATA
APPCORE --> VIEWMODEL
VIEWMODEL --> VIEW STATE --> VIEW
UI-INITIATED VIEW CHANGES
VIEW --> EVENT --> APPCORE (HANDLER) --> VIEWMODEL
--> APPSTATE
APPCORE (OPERATION) --> DDATA0
CONTROL EVENT-INITIATED CHANGES
EVENT --> APPCORE (HANDLER) --> VIEWMODEL
EVENT --> APPCORE (HANDLER) --> APPSTATE
EVENT --> APPCORE (HANDLER) --> APPCOMMAND