Behavior pattern: observer pattern

Keywords: Programming Django Python

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()

Posted by tolputt-craig on Thu, 14 May 2020 07:13:25 -0700