FlatRate(fee) and PerKg(rate) each expose cost(weight). Shipment(weight, strategy) delegates price() to whichever strategy object it holds, and set_strategy() swaps it live. The shipment never contains pricing math itself.s = Shipment(3, PerKg(40)); s.price(); s.set_strategy(FlatRate(99)); s.price()
120 then 99
Same shipment, different interchangeable pricing objects.
Duck typing is the whole pattern here — no base class required.
Store the strategy as an attribute.