What can we say about the characteristics of lava flow (no metaphors YET, I refer to RL lava)?
- it's practically impossible to stop/revert lava flow, it can either continue in the current "channel" or get routed in a new one(s)
- if there's no clear channel/route, lava will find its way in an uncontrollable manner
- lava doesn't just pass by, it marks its way along the whole path with fire & razed ground
Neat, but how does it correspond to software architecture?
- Lava flow represents the utilized "capacity" of development team. Developers will create code regardless of whether architecture is ready/makes sense (because they have features to deliver & no company can afford having expensive personnel doing nothing) - this corresponds to the "unstoppableness" of the (lava) flow.
- Channel lava flows in is a current architecture (conventions, applied patterns, used concepts): not the intended (planned) one, but the one that is actually applied (intentionally or not).
- Re-routes of lava (moments when it's zig-zagging) reflect architectural changes that are intended to improve the direction, but leave the hot stream of burning lava behind. That stream represents the fact that the new architecture is applied only to the new stuff, while the "tail" of past architectural decisions is still present in the majority of the code-base. Yes, not just a single "previous" architecture, but all "previous" architectures: each pivot represents a single architectural change which was not consistently applied across whole (incl. so-called "legacy") code-base.
These 3 observations constitute what is known as Lava Flow Anti-pattern.
Making sense out of the metaphor
Lava Flow anti-pattern is an important real-life tech debt generator. It depicts the cost of being inconsistent (or inconsequential) in applying heavily impactful changes - because pragmatically speaking:
convention/architecture consistency is much more important than its perfection
What's the negative effect of Lava Flow anti-pattern?
- higher cognitive load & entry threshold (system architecture is harder to understand)
- higher operational (maintenance) cost (due to potential code duplication and/or cross-concept cooperation)
- culture-breaking broken window effect (lowering the engineering standards)
How to fight Lava Flow anti-pattern?
Each new architecture/pattern/convention proposal should be by default accompanied by the feasible transition plan:
- what's the expected final outcome
- how to get there
- how to measure/verify the progress (of getting there)
The change should NOT be considered concluded, until it's fully applied across the whole code-base (or at least its actively developed part). No new change should be allowed (to be conducted) until all the previous changes are confirmed to be finalized (aka "keep the number of parallel experiments/changes limited").
Why should you care?
The reasons should be quite obvious at this point:
Sum up the high engineer staff turnover with strong "fatherhood/motherhood" instincts (over your own code) and the irrational belief that "this time we'll do it all right, kk?" - what comes out of this formula is a trend of building a greenfield within a brownfield, while forgetting about all what was done before (including all the lessons learned) - especially the operational cost of its maintenance (expressed in both mandays & a cognitive load required).
Your architecture(s) has to either go in unison or have very clear boundaries, so its parts can truly evolve independently. Whether you can ensure that is a good measure of engineering team's maturity.