Design Pattern Examples
Overview of object-oriented design patterns
observersubject_numberproducer.py
Go to the documentation of this file.
11
12from abc import ABC, abstractmethod
13
14
15
24
27 @abstractmethod
28 def NumberChanged(self) -> None:
29 pass
30
31
32
34
35
36
48class IEventNotifications(ABC):
49
50 @abstractmethod
51 def SubscribeToNumberChanged(self, observer : IObserverNumberChanged) -> None:
52 pass
53
54
55 @abstractmethod
56 def UnsubscribeFromNumberChanged(self, observer : IObserverNumberChanged) -> None:
57 pass
58
59
60
62
63
64
73class INumberProducer(ABC):
74
75
76 @abstractmethod
77 def Update(self) -> None:
78 pass
79
80
84 def FetchNumber(self) -> int:
85 pass
86
87
88
90
91
92
100class ObserverSubject_NumberProducer(IEventNotifications, INumberProducer):
101
102
103 def _NotifyNumberChanged(self) -> None:
104 # Copy the list so observers can change the original observers
105 # during the notification (this isn't strictly needed in this
106 # example but it is good practice for any notification system
107 # that handles multiple observers where multiple threads might
108 # be in play or observers can unsubscribe at any time, even in
109 # the event notification).
110 observers = self._observers.copy()
111 for observer in observers:
112 observer.NumberChanged();
113
114
115
122 def _FindObserver(self, observer : IObserverNumberChanged) -> int:
123 foundIndex = -1
124 try:
125 foundIndex = self._observers.index(observer)
126 except ValueError:
127 # observer was not found
128 pass
129 return foundIndex
130
131
132
140 def _ContainsObserver(self, observer : IObserverNumberChanged) -> bool:
141 foundObserver = self._FindObserver(observer)
142 return foundObserver != -1
143
144
145
146 def __init__(self) -> None:
147 self._observers = [] # type: list[IObserverNumberChanged]
148 self._number = 0
149
150
154
155
156
157 def Update(self) -> None:
158 self._number += 1
160
161
162 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
163 # Implementation of the INumberProducer interface.
164 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
165
166
170 def FetchNumber(self) -> int:
171 return self._number
172
173
174 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
175 # Implementation of the IEventNotifications interface.
176 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
177
178
192 def SubscribeToNumberChanged(self, observer : IObserverNumberChanged) -> None:
193 if not self._ContainsObserver(observer):
194 self._observers.append(observer)
195
196
197
211 def UnsubscribeFromNumberChanged(self, observer : IObserverNumberChanged) -> None:
212 if self._ContainsObserver(observer):
213 self._observers.remove(observer)
None UnsubscribeFromNumberChanged(self, IObserverNumberChanged observer)
Call this with an observer to unsubscribe from the "number changed" event.
None SubscribeToNumberChanged(self, IObserverNumberChanged observer)
Call this with an observer to subscribe to the "number changed" event.
None NumberChanged(self)
This is called whenever the number in the ObserverSubject_NumberProducer object is changed.
None UnsubscribeFromNumberChanged(self, IObserverNumberChanged observer)
A client calls this to unsubscribe an observer from this class instance so notifications are no longe...
None _NotifyNumberChanged(self)
Helper method to notify all observers that the number has changed.
bool _ContainsObserver(self, IObserverNumberChanged observer)
Helper method to determine if the specified observer is already present in the list of observers for ...
int _FindObserver(self, IObserverNumberChanged observer)
Helper method to retrieve the iterator to the specified observer if the observer is in the list.
None SubscribeToNumberChanged(self, IObserverNumberChanged observer)
A client calls this to subscribe an observer to this class instance for notifications about changing ...