Using the subject/observer pattern¶
import sys
sys.path.append('../..')
The subject/observer pattern requires in this library to import following (as needed):
from responsive.subject import Subject
from responsive.observer import DefaultObserver
Testing the subject/observer feature. The notification allows specifying no parameters, positional parameter or keyword arguments or both. It is in the responsiblity of the concrete subject to provide sufficient information to the observers. We are using a default server implementation which is - to be clear - mainly for testing and demonstration purpose.
observer = DefaultObserver()
subject = Subject()
subject.add_observer(observer)
subject.notify('just a test', reason="test")
for subject, args, kwargs in observer:
print(f"subject has notified with {args} and {kwargs}")
subject has notified with ('just a test',) and {'reason': 'test'}
Now we change the interest of the observer and we register for the concrete interest.
observer.set_interests({"reason": lambda value: value == "test2"})
observer.clear()
subject.notify(reason="test1", message="it's a test")
print(list(kwargs for _, _, kwargs in observer))
subject.notify(reason="test2", message="it's another test")
print(list(kwargs for _, _, kwargs in observer))
[] [{'reason': 'test2', 'message': "it's another test"}]
As you can see the first ouput is an empty list since that interest does not match the value for reason (see lambda function). Another possibility might be that the attribute that you are interested in was not part of the notification. The final output provides you an update since name and value did match.
What is this for? Consider a book (converted into responsible data). You could develop a text widget as observer that does register once for the title and once for the name of the author. Each time you change the data the widgets would be updated. The first example at the beginning was updated on any change which is also a valid usecase but not the only one.