Replace growing if/elif chains with strategy registries (dicts of callables) or functools.singledispatch for type-based dispatch. Both keep open/closed design: add a new variant without editing the dispatcher core.
Mutable default registries - shared dict mutated at runtime leaks state across tests. Fix: copy registries or use immutable mappings (MappingProxyType).
KeyError vs explicit error - raw dict access gives vague errors. Fix: wrap with helpful ValueError messages.
singledispatch on methods - registering on methods is awkward; use standalone functions or singledispatchmethod.
elif still growing elsewhere - dispatch only helps at one boundary; duplicate branches in callers mean wrong abstraction level. Fix: dispatch once at the facade.
Untested default branch - singledispatch base that always raises hides missing registrations until runtime. Fix: test each registered type.