## The Observer Design Pattern in Python. # Observers: stock investors # Observees: individual stocks. # Each Observee class must implement the following methods: # attach(newobserver) : attaches a new observer # remove(someobserver) : removes an observer # notify() : notifies all attached observers # Each Observer class must implement a # update(sourceobservee): respond to notifications from # the observee. # When something inside an observee object changes, which is of potential # interest to an observer, all the observers attached to the object are # notified. The notify function calls the update function inside each # observer. Different kinds of observers can implement different update # functions, so they can respond to the notification differently. Usually, # observer classes are subclasses of a common superclass for all observers. # Design patterns such as Observer are ways in which we can structure # objects effectively. The observer pattern is a template for objects # to interact autonomously (i.e., the interaction is encapsulated completely # within the objects). # The observee class: class stock: def __init__(self,sym, initprice): self.symbol = sym self.price = initprice self.oldprice = 0 # needed to observe changes self.observers = [] # list of attached observers self.justsplit = False # signal to indicate when stock split # constructor def changeprice(self,dp): # records a change in price self.oldprice = self.price self.price += dp # use negative numbers for decrease self.notify() # notify all observers *************** # changeprice def split(self): # stock splits - shares should double self.price = self.price / 2.0 self.oldprice = self.price # don't confuse split with drop in price self.justsplit = True # set signal that indicates split occured self.notify() # notify observers of the split ******** self.justsplit = False # reset justsplit after notify. # split ##### Additional methods implement the observer pattern interface: def attach(self,x): # add new observer x self.observers.append(x) def remove(self,x): # remove observer x self.observers.remove(x) def notify(self): # notify all observers i = 0 while iobv.price): # stock fell; BUY! print "BUY BUY BUY" self.investments[obv.symbol] += 200 # buy 200 shares # update # bullinvestor class bearinvestor(investor): def __init(self): investor.__init__(self) # call the superclass constructor # init ##### observer pattern interface: def update(self,obv): # respond to observee notify: if (obv.justsplit): # double shares after split self.investments[obv.symbol] *= 2 # double shares if (obv.oldprice>obv.price): # stock fell; SELL OFF! print "DUMP",obv.symbol,"NOW!" self.investments[obv.symbol] = 0 obv.remove(self) # stop observing this stock if (obv.oldprice