When to Use an Observer vs. a Plugin: A Decision Guide
When to Use an Observer vs. a Plugin: A Decision Guide
~7 Min. Lesezeit Zuletzt aktualisiert am August 9, 2026
Block 4 has shown nothing but observers - AwardPointsOnOrderPlaced (chapter 30), ReversePointsOnCreditmemoSave (chapter 31), the custom mironsoft_loyalty_customer_tier_changed event (chapter 35). Block 5 starts in chapter 38 with plugins - and chapter 39's very first plugin example already shows something no observer could ever do: actually change a method's return value. This chapter makes the distinction explicit before block 5 dives into the mechanics.
The one structural boundary
An observer receives objects by reference and absolutely can modify them - that's exactly why chapter 30's $order->setData('loyalty_points_earned', ...) works. What an observer cannot do: influence the return value of the method that dispatched the event, or intercept and replace its arguments before it runs. sales_order_place_after fires after the order has already been placed - the observer comments on the outcome, it no longer gets a vote.
A preview example from block 5
Chapter 39 (block 5) plugs the checkout totals collector to actually factor a points-based discount into the order total. That requires a plugin: the returned total amount has to be actively changed before it's used in checkout - an observer could, at best, log the already-final amount, never correct it.
Decision checklist
- Does the return value or arguments of a specific method need to change? → Plugin. Structurally impossible for an observer.
- Is "something extra happens after something occurred" enough, without altering the original flow? → Observer. Simpler, more decoupled, supports any number of independent subscribers (chapter 29).
- Does the target location dispatch an event at all? Many pure getters and calculations don't. → No event present means only a plugin (or a preference, chapter 40) remains an option.
- Is the target method
finalor private? Plugins can't intercept such methods. → Only an observer (if a matching event exists) or a preference are viable. - Does execution order relative to other code need to be exact and explicitly controllable? → Plugin with
sortOrder(chapter 43) - observers only have the indirect means from chapter 36 for that.
Side by side
- Observer: publish/subscribe, any number of independent subscribers, no access to the return value, no explicit
sortOrder, runs synchronously and blocks (chapter 29), typical for "a fact occurred, react to it". - Plugin: a targeted interceptor on exactly one method of exactly one class/interface, can actively change arguments and the return value (
before/after/around), explicit, numericsortOrder, tightly coupled to an exact method signature and therefore more sensitive to core updates (block 5 explores this risk further starting chapter 42).
Tipp: The two techniques aren't mutually exclusive - this module ultimately uses both side by side: observers for additive side effects (this block), plugins wherever an existing return value genuinely needs to be altered (block 5). The question is never "observer or plugin in general", but "for this one concrete need".
That wraps up block 4: nine chapters, two observers, a dedicated crongroup, a cron job with robust error handling, a self-dispatched event, and a clear decision guide for the future. Block 5 starts in chapter 38 with plugins in detail - beginning with before/after/around themselves, before chapter 39 implements this series' first real plugin use case: the points discount in checkout.