Behavior mode:
Observer mode:
Also known as: event subscriber, Listener, event subscriber, Listener, Observer
intention
The observer pattern is a behavioral design pattern that allows you to define a subscription mechanism, Multiple "watch" other objects of an object can be notified when an object event occurs.
Core: the observed and the observer establish an automatic triggering relationship
pattern analysis
In the water heater model
Monitored: the temperature of the water heater Monitor: different water temperature, different monitors will respond in time
Observed:
- Add listener
- Delete listener
- Notify the listener. Trigger the observer's provider
Use scenario
- django signal mechanism
2. Push model and pull model
*Push model: pushed by the observer to the observer *Pull model:
#!/usr/bin/env python from abc import ABCMeta, abstractmethod class Observer(metaclass=ABCMeta): """ //Observer base class: """ @abstractmethod def update(self, water_heater): """ //Subscribe to update events :param water_heater: :return: """ print('xxx WaterHeater:{}'.format(water_heater)) class Observable(metaclass=ABCMeta): """ //Observed base class: """ def __init__(self): self.__observers = [] def __str__(self): return f"observers:{self.__observers}" def register(self, observer): if not isinstance(observer, Observer): raise TypeError('observer must be instance of Observer') self.__observers.append(observer) def unregister(self, observer): self.__observers.remove(observer) def notice(self): """ //Notify subscribers of events :return: """ for o in self.__observers: # if hasattr(o, 'update'): o.update(self) class WaterHeater(Observable): """ //heater """ def __init__(self): super().__init__() self.__temperature = 25 def __str__(self): print(super().__str__()) return f"cur temperature:{self.__temperature}" @property def temperature(self): return self.__temperature @temperature.setter def temperature(self, val): self.__temperature = val print(self) self.notice() class Account(Observable): """ //Record of landing place """ def __init__(self): super().__init__() self.__city_history = list() def __str__(self): print(super().__str__()) return f"cur city_history:{self.__city_history}" @property def city(self): return self.__city_history[-1] @city.setter def city(self, val): if val not in self.__city_history: self.__city_history.append(val) print(self) self.notice() class WashMode(Observer): """ //Bath mode """ def update(self, water_heater: WaterHeater): if 50 < water_heater.temperature < 70: print('is good time at wash') else: print('not good time at wash') class DrinkMode(Observer): """ //Drinking water mode """ def update(self, water_heater: WaterHeater): if water_heater.temperature >= 80: print('is good time at drink') else: print('not good time at drink') class SmsMode(Observer): """ //SMS notification """ def update(self, account: Account): """ :param account: :return: """ print('sms notify ', account.city) pass class EmailMode(Observer): """ //Email notification """ def update(self, account: Account): """ :param account: :return: """ print('email notify ', account.city) def test_water_mode(): water_heater = WaterHeater() wash_observer = WashMode() drink_observer = DrinkMode() water_heater.register(wash_observer) water_heater.register(drink_observer) water_heater.temperature = 60 water_heater.temperature = 100 def test_other_area_login(): login = Account() email = EmailMode() sms = SmsMode() login.register(email) login.register(sms) login.city = 'Beijing' login.city = 'Shanghai' def main(): # test_water_mode() test_other_area_login() pass if __name__ == '__main__': main()