Code Architecture for Interaction

Posted Tuesday, March 15, 2022 by Sri.Tagged CONCEPT, INTERACTION
EDIT STATUS:first draft

At its core, an interactive application just does this:

  1. show data changing over time
  2. 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