#!/usr/bin/python import sys # ---------------------------------------------------------------- class Observable(dict): """ A class of thing that can be observed. When its notifyObservers() method is called with an event, it passes that event on to its observers. """ def addObserver(self, event, observer): if self.has_key(event): self[event].append(observer) else: self[event] = [observer] def notifyObservers(self, event): if self.has_key(event): for observer in self[event]: observer.observeEvent(event) # ---------------------------------------------------------------- class Observer(object): """ A class of thing that observes an Observable. The Observable will calls the Observer's observeEvent() method. """ def __init__(self, name): self.name = name def observeEvent(self, event): sys.stdout.write('=== %s: "%s"\n' % (self.name, event)) # ---------------------------------------------------------------- class AnimalDetector(Observable): """ This class notifies all its observers if a string contains a particular animal. """ def detect(self, line): animals = ('goat', 'sheep', 'duck', 'horse', 'platypus') for a in animals: if line.find(a) != -1: self.notifyObservers(a) # MAIN ----------------------------------------------------------- animalD = AnimalDetector() alice = Observer('Alice') bert = Observer('Bert') chris = Observer('Chris') dave = Observer('Dave') # Notice how we have multiple observers looking for the same event in # the following code. Also notice how the 'cow' event will never trigger # for bert, because the AnimalDetector doesn't dispatch an event for # cows! animalD.addObserver('goat', alice) animalD.addObserver('cow', bert) animalD.addObserver('goat', bert) animalD.addObserver('goat', chris) # same as alice! animalD.addObserver('platypus', chris) animalD.addObserver('duck', dave) animalD.addObserver('platypus', dave) for line in iter(sys.stdin.readline, ""): # iter/readline for line-buffering animalD.detect(line)