In [1]:
from time import sleep
from random import randint
from abc import abstractmethod

Observer¶

In [2]:
class ISubscriber():
    @abstractmethod
    def updateTemperature(self, temperature):
        pass
In [6]:
class Gismeteo(ISubscriber):
    def __init__(self):
        print('Widget Gismeteo activated')
    
    def updateTemperature(self, temperature):
        print('Gismeteo reports about weather: {} C degrees now'.format(temperature))

class MeteoUa(ISubscriber):
    def __init__(self):
        print('Widget MeteoUa activated')
    
    def updateTemperature(self, temperature):
        print('MeteoUa reports about weather: {} C degrees now'.format(temperature))

class WetterCom(ISubscriber):
    def __init__(self):
        print('Widget WetterCom activated')
    
    def updateTemperature(self, temperature):
        print('WetterCom reports about weather: {} degrees now'.format(32 + 9*temperature/5))
In [11]:
class Thermometer:
    def __init__(self):
        self._subscribers = []
        self._temperature = 20
        
    def measure(self):
        for i in range(0, 12):
            self._temperature += randint(-3, 3)
            self.notify()
            sleep(0.5)
    
    def attach(self, subscriber):
        self._subscribers.append(subscriber)
    
    def notify(self):
        for subs in self._subscribers:
            subs.updateTemperature(self._temperature)
        print('\n')
In [12]:
sub1 = Gismeteo()
sub2 = MeteoUa()
sub3 = WetterCom()
Widget Gismeteo activated
Widget MeteoUa activated
Widget WetterCom activated
In [13]:
thermometer = Thermometer()
thermometer.attach(sub1)
thermometer.attach(sub2)
thermometer.attach(sub3)
In [14]:
thermometer.measure()
Gismeteo reports about weather: 18 C degrees now
MeteoUa reports about weather: 18 C degrees now
WetterCom reports about weather: 64.4 degrees now


Gismeteo reports about weather: 17 C degrees now
MeteoUa reports about weather: 17 C degrees now
WetterCom reports about weather: 62.6 degrees now


Gismeteo reports about weather: 15 C degrees now
MeteoUa reports about weather: 15 C degrees now
WetterCom reports about weather: 59.0 degrees now


Gismeteo reports about weather: 18 C degrees now
MeteoUa reports about weather: 18 C degrees now
WetterCom reports about weather: 64.4 degrees now


Gismeteo reports about weather: 19 C degrees now
MeteoUa reports about weather: 19 C degrees now
WetterCom reports about weather: 66.2 degrees now


Gismeteo reports about weather: 16 C degrees now
MeteoUa reports about weather: 16 C degrees now
WetterCom reports about weather: 60.8 degrees now


Gismeteo reports about weather: 16 C degrees now
MeteoUa reports about weather: 16 C degrees now
WetterCom reports about weather: 60.8 degrees now


Gismeteo reports about weather: 19 C degrees now
MeteoUa reports about weather: 19 C degrees now
WetterCom reports about weather: 66.2 degrees now


Gismeteo reports about weather: 21 C degrees now
MeteoUa reports about weather: 21 C degrees now
WetterCom reports about weather: 69.8 degrees now


Gismeteo reports about weather: 22 C degrees now
MeteoUa reports about weather: 22 C degrees now
WetterCom reports about weather: 71.6 degrees now


Gismeteo reports about weather: 25 C degrees now
MeteoUa reports about weather: 25 C degrees now
WetterCom reports about weather: 77.0 degrees now


Gismeteo reports about weather: 24 C degrees now
MeteoUa reports about weather: 24 C degrees now
WetterCom reports about weather: 75.2 degrees now


Memento¶

In [35]:
class Memento:
    def __init__(self, content, style):
        self._content = content
        self._style   = style
    
    @property
    def content(self):
        return self._content
    
    @property
    def style(self):
        return self._style
    
    def __str__(self):
        return 'Memento(content: {}, style: {})'.format(self.content, self.style)
In [36]:
class Document:
    def __init__(self):
        self._content = ''
        self._style = 'none'
    
    def setStyle(self, newStyle):
        self._style = newStyle
    
    def updateContent(self, newContent):
        self._content = newContent
            
    @property
    def content(self):
        return self._content
    
    @property
    def style(self):
        return self._style
    
    def saveState(self):
        return Memento(self._content, self._style)
    
    def restoreState(self, state):
        self._content = state.content
        self._style   = state.style
    
    def __str__(self):
        return 'Document(content: {}, style: {})'.format(self.content, self.style)
In [37]:
class History:
    def __init__(self):
        self._history = []
        
    def getHistory(self):
        for h in self._history:
            print(h)
    
    def add(self, state):
        self._history.append(state)
    
    def undo(self):
        #return self._history[-1]
        return self._history.pop()
In [38]:
history = History()
In [39]:
doc = Document()
history.add(doc.saveState())
history.getHistory()
Memento(content: , style: none)
In [40]:
doc.updateContent('abde')
doc.setStyle('style 1')
history.add(doc.saveState())
history.getHistory()
Memento(content: , style: none)
Memento(content: abde, style: style 1)
In [41]:
doc.updateContent('ABCDE')
doc.setStyle('style capital')
history.add(doc.saveState())
history.getHistory()
Memento(content: , style: none)
Memento(content: abde, style: style 1)
Memento(content: ABCDE, style: style capital)
In [42]:
print(doc)
Document(content: ABCDE, style: style capital)
In [43]:
doc.updateContent('ABCDE abcd')
doc.setStyle('style mixed')
print(doc)
Document(content: ABCDE abcd, style: style mixed)
In [44]:
doc.restoreState(history.undo())
In [45]:
print(doc)
Document(content: ABCDE, style: style capital)
In [46]:
doc.restoreState(history.undo())
print(doc)
Document(content: abde, style: style 1)
In [47]:
doc.restoreState(history.undo())
print(doc)
Document(content: , style: none)
In [ ]: