原文鏈接:https://www.cnblogs.com/-wenli/p/10967306.html
監聽模式
我們希望在一個對象的狀態改變時更新另一個對象,即類似MCV模式,當多個視圖共用一組模型數據時,只要有一個視圖進行了數據的修改,其他視圖都可以進行更新。
上面的問題就是監聽模式需要去解決的。怎麼解決?
定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都可以得到通知,並根據通知按需進行自動更新
狀態改變後,所有的依賴對象都將得到通知(廣播通知)
重點 —— 在被觀察者類中,加入一個arrayList存放觀察者,這裏就涉及到一個挺有意思的問題,被觀察者對不同的觀察者發送推送消息是有順序的。
應用場合:
- 拍賣競價,出價後,通知各個競拍者進行競價
- 服務器作爲被觀察者,服務器狀態變化後,通知發給各個客戶端,各個客戶端做相應的行爲
設計一個被觀察者,一組觀察者。
被觀察者需要有三個基本的方法:
- 添加觀察者
- 刪除觀察者
- 監聽目標變化並通知觀察者
觀察者至少要有一個方法:
- 接收到被觀察者的通知後,做出相應的callback。
基本代碼:
# -*- coding: utf-8 -*-
# 定義一個發佈者/被觀察者
class Publisher:
def __init__(self):
# 用於放置觀察者
self.__observers = []
#TODO:檢查觀察者列表是否爲空
def hasObserver(self):
return False if not self.__observers else True
#TODO:添加觀察者
def addObserver(self,observer):
# 添加之前檢查是否存在
if observer not in self.__observers:
self.__observers.append(observer)
else:
print("Failed to add:{}".format(observer))
#TODO:移除觀察者
def removeObserver(self,observer):
try:
self.__observers.remove(observer)
except ValueError:
print("Failed to remove:{}".format(observer))
#TODO:發佈消息
def notify(self):
for observer in self.__observer:
observer.update(self)
# 定義一個訂閱者/觀察者
class Observer:
def update(self,publiser):
pass
實例
from Observer import Publisher,Observer
class DefaultFormatter(Publisher):
def __init__(self,name):
super(DefaultFormatter, self).__init__()
self.name = name
self._data = 0
# TODO: 返回關於發佈者名稱和 _data值的信息
def __str__(self):
return "{}:{} has data = {}".format(type(self).__name__,self.name, self._data)
def data(self):
return self._data
def setData(self, value):
try:
self._data = int(value)
except ValueError as e:
print('Error:{}'.format(e))
else:
print('修改了')
self.notify()
class HexFormatter(Observer):
def update(self, publiser):
print("hex data = {}".format(hex(publiser.data())))
class BinaryFormatter(Observer):
def update(self, publiser):
print("Bin data = {}".format(bin(publiser.data())))
if __name__ == '__main__':
# 創建publisher和observer
default = DefaultFormatter("test")
hexFormatter = HexFormatter()
binFormatter = BinaryFormatter()
default.addObserver(hexFormatter)
default.addObserver(binFormatter)
# publisher狀態更新
default.setData(1)
default.setData(10)
# 移除一個observer
default.removeObserver(hexFormatter)
default.setData(20)