Container Object Notification: Best Practices

I have two classes: account and operator. The account contains a list of operators. Now that the operator (in the list) receives the message, I want to notify the Account object in order to execute some business logic.

I am thinking of three alternatives on how to achieve this:

1) Hold the link in the Operator to the [Account] object and call the methods directly. Not really good due to circular links.

2) Use events. As far as I know, Python has no built-in event handling mechanism. So this is a little difficult to implement.

3) Do not send messages directly to operators. Instead, use only accounts and inside them, internal, handlers. This is a bit limiting, because in this case I cannot pass references to statements.

I wonder which approach is most beneficial from an architectural point of view. How do you usually complete this task?

It would be great if you could specify fragments in Python.

+4
source share
5 answers

You think too much about it. Jokes aside. Python is not C ++; your problems are not problems in Python. Just write what makes sense in your area of ​​concern.

"Not really good due to circular links."

Why not? Circularity is irrelevant here. Bidirectional relationships are great things. Use them. The garbage Python collects them just fine, without even thinking about its part.

What is the possible problem you have with a mutual (bi-directional) relationship?

"... only work with accounts and inside them with internal handler statements. This is a bit limiting, because in this case I can’t pass links to statements."

What? Your operators, Python objects, pass everything you need. All Python objects are (in fact) links, not sweating.

What is your problem with manipulating Operator objects?

+5
source

There is no one-time-for-all solution for the Observer template. But it's usually best to define an EventManager object where interested parties can register for certain events and publish these events whenever they happen. It just creates fewer dependencies.

Note that you need to use a global instance of EventManager, which can be problematic during testing or from a general OO perspective (this is a global variable). I highly recommend not skipping EventManager all the time because it clutters your code.

In my own code, the β€œkey” for registering events is an event class. EventManager uses a dictionary (event class β†’ observer list) to find out what event is happening there. In the notification code, you can use dict.get(event.__class__, ()) to find your listeners.

+3
source

I would use event handling. You do not need to implement it yourself - I use pydispatcher for this kind of event handling, and it always worked very well (it uses weak links inside to avoid the circular link problem).

In addition, if you use the gui framework, you may have an event framework that you can connect to, for example PyQt has signals and slots.

+3
source
 >>> class Account(object): ... def notify(self): ... print "Account notified" ... >>> class Operator(object): ... def __init__(self, notifier): ... self.notifier = notifier ... >>> A = Account() >>> O = Operator(A.notify) >>> O.notifier() Account notified >>> import gc >>> gc.garbage [] >>> del A >>> del O >>> gc.garbage [] 

One thing you may not know about instance methods is that they are related when searching using point syntax. In other words, the A.notify expression automatically binds the self parameter pointing to A. Then you can save the link to this function without creating useless garbage.

Finally, you can always use Kamaelia for this type of thing.

+3
source

There are snippets of Observer patterns across the Internet. A good source of reliable code is the active state, EG:

http://code.activestate.com/recipes/131499/

0
source

All Articles