I have two classes: Account and Operator. Account contains a list of Operators. Now, whenever an operator (in the list) receives a message I want to notify Account object to perform some business logic as well.
I think of three alternatives on how to achieve this:
1) Hold a reference within Operator to the container [Account] object and call methods directly. Not absolutely good because of circular references.
2) Use events. As far as I know there is no built-in event handling mechanism in Python. So, this one is a bit tricky to implement.
3) Don't send messages to Operators directly. Instead, operate only Accounts, and within them, internally, handler operators. This one is a bit limiting because in this case I cannot pass around references to operators.
I wonder which approach is the most advantageous from the architectural point of view. How do you usually handle this task?
It would be great if you could point out snippets in Python.
You're over-thinking this. Seriously. Python isn't C++; your concerns are non-issues in Python. Just write what makes sense in your problem domain.
" Not absolutely good because of circular references."
Why not? Circularity is of no relevance here at all. Bidirectional relationships are great things. Use them. Python garbage collects them just fine without any thinking on your part.
What possible problem do you have with mutual (birectional) relationships?
"...operate only Accounts, and within them, internally, handler operators. This one is a bit limiting because in this case I cannot pass around references to operators. "
What? Your Operators are Python objects, pass all you want. All Python objects are (in effect) references, don't sweat it.
What possible problem do you have with manipulating Operator objects?
There is no "one-size-fits-all" solution for the Observer pattern. But usually, it's better to define an EventManager object where interested parties can register themselves for certain events and post these events whenever they happen. It simply creates less dependencies.
Note that you need to use a global EventManager instance, which can be problematic during testing or from a general OO point of view (it's a global variable). I strongly advise against passing the EventManager around all the time because that will clutter your code.
In my own code, the "key" for registering events is the class of the event. The EventManager uses a dictionary (event class -> list of observers) to know which event goes where. In the notification code, you can then use dict.get(event.__class__, ())
to find your listeners.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With