TransWikia.com

Creating a "pass-through" dynamic model

Software Engineering Asked by McArthey on February 16, 2021

We have a layer that exists in our architecture that, for lack of a better term, bears the responsibility of defining the common models. In other words, when systems need to communicate, rather than point-to-point, this layer is used.

|----------|        |--------|         |----------|
| System A |   ==>  | Common |   ==>   | System B |
|----------|        |--------|         |----------|

The issue we are currently facing is that System B has a requirement to allow variable data depending on a specific identifier. For example, for id “X”, they will want fields 1,2,3, but for id “Y”, they will want fields 3,6,7.
While it is simple enough to create a variable structure such as the below, the challenge is that this breaks our concept of separation of concerns.

{
    "uniqueId": "X",
    "variableData":
    {
        "field1": "value",
        "field2": "value",
        "field3": "value"
    }
}

In other words, this requires that System A has knowledge of the specific requirements of System B. This seems less than ideal to me. Another thought is that we could define the model as below, but this potentially results in a large, mostly empty, model.

{
    "uniqueId": "X",
    "variableData":
    {
        "field1": "value",
        "field2": "value",
        "field3": "value",
        "field4": "value",
        "field5": "value",
        "field6": "value",
        "field7": "value"
    }
}

I’m guessing this has been addressed and resolved through a pattern but I’m not able to locate what this might be called. Or is this a simple matter or weighing the pros and cons to come to a solution for our implementation?

2 Answers

First think about the possibility that these are are two different classes of objects in your domain (as proposed by doubleYou).

But should you really want dynamic objects ('dynamic object' appears to be a good name for the pattern; more informally, i've seen it called 'duck typing' as well) then there are several options available:

  • There are various representation formats well suited to transferring dynamic objects: JSON; XML (using schemas might complicate things, but is doable); RDF (various schema and ontology languages will help you define meaning); and, when using C#, C# has the keyword dynamic to define dynamic objects.
  • From computer game design there are Entity-Component and Entity-Component-System architectures from which you can borrow ideas (and if you really want to libraries/frameworks to implement it).
    In an ECS architecture entities are the things in the game such as an enemy or the player-character; components are structs of data values to carry data about the entities; and, systems do the calculations. For example the graphics system retrieves all entities with a sprite and a position component and renders them. And, if an entity has a fly speed component it can fly; to change the 'type' of a non-flying enemy into a flying enemy we attach a fly speed component to it. Entities themselves are identifiers and do not contain any data, all data is in the components, all behaviour is in the systems.
    In our (non-computer game) software we can use something inspired by Entity-Component-(System) architecture to gain objects with dynamically changeable type.

Answered by Kasper van den Berg on February 16, 2021

Clearly, you're missing some concept in your model. From the perspective of System B, X and Y appear to be distinct types with separate properties.

Furthermore System B obtains its model from the common model. So the information about whether you're dealing with an X or a Y must be present there somehow, along with the relevant field data.

I can only see two scenarios:

  • X and Y are merely System B-specific representations of some entity already available in the common model. In this case, there's no need for empty fields - just have System B's adapter transform the data accordingly.

    For example, the common model has a ExistsSince field that translates into Birthday and Age fields in System B's X and Y types, respectively.

  • X and Y are fundamentally different in important ways, such that properties of one simply make no sense for the other. In this case, they should be represented separately in your common model as well.

    I assume you're dealing with this case.

Now, if we assume that X and Y are fundamentally different, there's really no point in defining shared properties that only one of them ever uses. Instead they'll have separate representations in the common model, each defining only the fields that make sense.

Note that there may still be a mismatch between how the information is represented in your common model vs your subsystems. This translation should be handled by each subsystem's adapter. You're not wrong in trying to keep the common model free from dependencies on any specific system - but you do need to make sure that your common model adequately reflects different concepts.

Answered by doubleYou on February 16, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP