Enjoy The Loop Blog
Sign in

Composition is not about swapping at Runtime

Composition Is Not About Swapping at Runtime

When developers talk about composition, one argument always comes up:

“It allows you to swap components at runtime.”

That sounds powerful, flexible and dynamic! And yet, it completely misses the point. Take this example:

settings_manager = SettingsManager(JsonExporter())

The usual explanation goes like this:

“Because we use composition, we can replace JsonExporter with XmlExporter at runtime.”

Technically true. Practically irrelevant.

How often do you actually swap implementations while your program is running? Almost never. So if that is the main benefit, composition feels like overengineering.

What Actually Matters

The real benefit of composition is much simpler and much more useful: You can change the behavior of your application without changing the source code. That is it.

From Code to Configuration

Without composition, behavior is hardcoded:

class SettingsManager:
    def export(self):
        exporter = JsonExporter()
        exporter.export()

Want XML instead of JSON? You must change the SettingsManager class, redeploy and hope nothing breaks. With composition, you move that decision outside the SettingsManager class:

if config["exporter"] == "json":
    exporter = JsonExporter()
elif config["exporter"] == "xml":
    exporter = XmlExporter()

settings_manager = SettingsManager(exporter)

Now the exporter is not a code decision anymore. It is a configuration decision.

Why This Is a Big Deal

This small shift has big consequences:

The Real Mindset Shift

Composition is not about asking: “Can I swap this object at runtime?” It is about asking: “Can I decide this outside of my code?”

That is a completely different way of thinking.

Where This Leads

Once you start seeing composition this way:

And most importantly:

You stop baking decisions into your code that should have been configuration all along.

Final Thought

Yes, composition allows you to swap components but that is not why it matters. It matters because it lets you move decisions out of your code and into configuration.

Written by Loek van den Ouweland on April 14, 2026.