Observer mode
The publish subscribe relationship between a single publisher (also known as a principal or observable object) and one or more objects (subscribers, also known as observers). Decoupling the relationship between adding publishers and subscriptions makes it easy to add and remove subscribers at runtime. For MVC, the publisher is the model, and the subscriber is the view.
Auction scenario:
Each bidder has a number plate. When Tiananmen Square wants to bid, they raise the number plate. When the bidder raises the plate, the auctioneer becomes the main body, updates the bidding price, and broadcasts the new price to all bidders (bidders).
Software scenario:
The RabbitMQ library can be used to add asynchronous messaging support to applications, supporting multiple messaging protocols such as HTTP and AMQP RbbitMQ can be applied in Python with the publish subscribe pattern, which is the observer design pattern.
News flow:
Use RSS, Atom, or other related formats. You can follow a news stream and receive a notification about each update.
Event driven system.
Listeners listen for specific events, which are triggered when the listening event is created. This event can be pressing a specific key, moving the mouse, and the event takes on the role of the publisher, while the listener takes on the role of the observer. Multiple listeners (observers) can be added to a single event (publisher).
Case study
A formatting program has a default formatting program that displays a value in decimal format, allowing for the addition and registration of more formatting programs. Every time the default formatting program is updated, it notifies the already registered formatting programs to take action. The program displays the new value in the relevant format.
(1) Define the Publisher class.
(2) Define the Default Formatter class and special__Init__And__Str__Method.
(3) Add methods for setting and obtaining data properties to the Default Formatter class.
(4) Define two observer classes.
(5) Add the main body of the program The first part of the main() function is as follows.
class Publisher:
def __init__(self):
self.observers = [] #save observer
def add(self, observer):
if observer not in self.observers:
self.observers.append(observer)
else:
print(f'Failed to add:{observer}')
def remove(self, observer):
try:
self.observers.remove(observer)
except ValueError:
print(f"Failed to remove:{observer}")
def notify(self):
print("all observer notification updates")
[o.notify(self) for o in self.observers]
class DefaultFormatter(Publisher):
def __init__(self, name):
Publisher.__init__(self)
self.name = name
self._data = 0
def __str__(self):
return f"{type(self).__name__}:'{self.name}' has data ={self._data}"
@property
def data(self):
return self._data
@data.setter
def data(self, new_value):
try:
self._data = int(new_value)
except ValueError as e:
print(f"Error:{e}")
else:
self.notify() #execution notification
"""
define two observers
"""
class HexFormatterObs:
def notify(self, publisher):
value = hex(publisher.data)
print(f"{type(self).__name__}: '{publisher.data}' has now hex data ={value}")
class BinaryFormatterObs:
def notify(self, publisher):
value = bin(publisher.data)
print(f"{type(self).__name__}:'{publisher.data}' has now bin data ={value}")
def main():
df=DefaultFormatter('test1')
print(df)
print("---------------------")
hf=HexFormatterObs()
df.add(hf)
df.data=3
print(df)
bf=BinaryFormatterObs()
df.add(bf)
df.data=21
print(df)
print("----------hello-----------")
df.data='hello'
print(df)
print("----------15.8-----------")
df.data=15.8
print(df)
if __name__== '__main__':
main()
# try:
# print("33333")
# except:
# print("wwww")
# else:
# print("else")
Execution results.
DefaultFormatter:'test1' has data =0
---------------------
all observer notification updates
HexFormatterObs: '3' has now hex data =0x3
DefaultFormatter:'test1' has data =3
all observer notification updates
HexFormatterObs: '21' has now hex data =0x15
BinaryFormatterObs:'21' has now bin data =0b10101
DefaultFormatter:'test1' has data =21
----------hello-----------
Error:invalid literal for int() with base 10: 'hello'
DefaultFormatter:'test1' has data =21
----------15.8-----------
all observer notification updates
HexFormatterObs: '15' has now hex data =0xf
BinaryFormatterObs:'15' has now bin data =0b1111
DefaultFormatter:'test1' has data =15