Dataflow: Minimise dependency chains

Intent

Minimise dependency chains by centralising shared logic in a Shared Part (comparable to the Mediator pattern).

Problem

There is a practical limit of three dependency levels across templates. Once you exceed three levels, cache inconsistencies can occur.

Example:

This example shows a “chain of results” across templates that exceeds three dependency levels.

A calculation is performed in Reconciliation 1 and stored as a result. That result is picked up in Reconciliation 2, extended with additional logic, and stored again. Continuing this pattern until Reconciliation 4 can lead to cache issues.

More information is available in the Dependencies and cache documentation. There is also a community example.

Solution

Centralise shared calculations in a Shared Part and rely on customs / database variables as the source of truth. This reduces direct template-to-template dependencies and makes templates collaborate indirectly through the Shared Part.

This approach helps avoid the “chain of results” cache issue described above.

It also improves separation of concerns by keeping templates focused on presentation while the Shared Part contains the reusable logic.

Structure

Examples / Applicability

Use a Shared Part to centralise logic and calculations. Prefer reading from the same customs / database variables across templates instead of “pushing” intermediate results forward through multiple templates.

Keep HTML templates focused on input fields, rendering variables, and lightweight calculations that are not reused elsewhere.

Real-World Analogy

Pilots of aircraft that approach or depart the airport control area don’t communicate directly with each other. Instead, they speak to an air traffic controller, who sits in a tall tower somewhere near the airstrip. Without the air traffic controller, pilots would need to be aware of every plane in the vicinity of the airport, discussing landing priorities with a committee of dozens of other pilots. That would probably skyrocket the airplane crash statistics.

The tower doesn’t need to control the whole flight. It exists only to enforce constraints in the terminal area because the number of involved actors there might be overwhelming to a pilot.

How to implement

  • Identify any result chains that approach or exceed three dependency levels.
  • Move the shared calculation logic into a Shared Part.
  • Store intermediate values in customs / database variables (when appropriate) instead of cascading results across templates.
  • In templates, include the Shared Part and render outputs rather than re-implementing logic.

Pros and cons

Pros

  • Reducing the dependency levels and as a result avoiding cache issues
  • A better overview of data flow
  • Making performance more streamlined/unified across templates which depend on this Shared Part

Cons

  • Over time the Shared Part can become too complex
  • Since there is no strict split between logic and view in Liquid it could be quite cumbersome to centralise all calculations in a Shared Part