[PYTHON] Modèle de conception #Observer

J'ai pratiqué les modèles de conception afin de pouvoir écrire du code conscient du design. D'autres modèles de conception seront publiés fréquemment.

Préface

L'objectif principal est de comprendre quand, quoi et comment utiliser les modèles de conception. (Je suis nouveau en Java ou dans un langage à typage statique, et je n'ai pas une longue histoire de python, donc je pense qu'il y a des choses qui ne ressemblent pas à Pythonista. Si vous avez des suggestions, apprenez-moi.)

Cette fois, le modèle Observer concernant le comportement.

Qu'est-ce que l'observateur

Dans le modèle Observer, l'observateur est notifié lorsque l'état de la cible d'observation change. Le modèle Observer est utile pour décrire le traitement qui répond aux changements d'état.

Aperçu

L'exemple de programme créé ici permet à l'observateur d'observer un objet qui génère un grand nombre et d'afficher sa valeur. Cependant, la méthode d'affichage diffère selon l'observateur. DigitObserver affiche les valeurs numériquement, tandis que GraphObserver affiche les valeurs dans un graphique simple.

Diagramme de classe global

observer.py


from abc import ABCMeta, abstractmethod


class Observer(Exception):
    __meta__ = ABCMeta

    @abstractmethod
    def update(self, generator):
        pass

L'interface d'observateur est une interface qui exprime un «observateur». Des observateurs spécifiques implémentent cette interface.

C'est le NumberGenerator qui génère le numéro qui appelle la méthode de mise à jour. La méthode de mise à jour est une méthode permettant à NumberGenerator d'indiquer à l'observateur que "Mon contenu a été mis à jour. Veuillez également mettre à jour l'affichage."

number_generator.py


from abc import ABCMeta, abstractmethod


class NumberGenerator(metaclass=ABCMeta):

    __observers = []

    def add_observer(self, observer):
        self.__observers.append(observer)

    def delete_observer(self, observer):
        self.__observers.remove(observer)

    def notify_observers(self):
        for observer in self.__observers:
            observer.update(self)

    @abstractmethod
    def get_number():
        pass

    @abstractmethod
    def execute():
        pass

La classe NumberGenerator est une classe abstraite qui génère des nombres. La génération réelle du nombre (méthode d'exécution) et la partie pour obtenir le nombre (méthode get_number) sont des méthodes abstraites, qui s'attendent à être implémentées par la sous-classe.

Le champ observateurs est le champ qui stocke les observateurs qui observent le générateur de nombres.

add_observer est une méthode pour ajouter un observateur, et delete_observer est une méthode pour supprimer un observateur.

La méthode notify_observers dit à tous les observateurs: "Mon contenu a été mis à jour, veuillez mettre à jour votre affichage." Dans cette méthode, la méthode de mise à jour est appelée pour chaque observateur dans les observateurs.

random_number_generator.py


import random
from number_generator import NumberGenerator


class RandomNumberGenerator(NumberGenerator):

    __number = 0

    def __init__(self):
        self.__rand = random

    def get_number(self):
        return self.__number

    def execute(self):
        for i in range(0, 20):
            self.__number = self.__rand.randint(0, 50)
            self.notify_observers()

La classe RandomNumberGenerator est une sous-classe de NumberGenerator qui génère des nombres aléatoires.

Le champ aléatoire contient le générateur de nombres aléatoires et le champ numérique contient la valeur aléatoire actuelle.

La méthode get_number renvoie la valeur du champ numérique.

La méthode d'exécution génère 20 nombres aléatoires (entiers de 0 à 49) et utilise à chaque fois notify_observers pour notifier l'observateur.

digit_observer.py


import time
import logging
from observer import Observer


class DigitObserver(Observer):

    def update(self, generator):
        print('DigitObserver:' + str(generator.get_number()))
        try:
            time.sleep(1)
        except InterruptedError as e:
            logging.exception(e)

La classe DigitObserver est une classe qui implémente l'interface d'observateur et est utilisée pour afficher le nombre d'observations sous forme de "nombre". Utilisez la méthode Get_number de NumberGenerator donnée en argument dans la méthode de mise à jour pour obtenir le nombre et l'afficher. Il y a des intervalles pour que vous puissiez voir à quoi ressemble l'affichage.

graph_observer.py


import sys
import time
from observer import Observer


class GraphObserver(Observer):

    def update(self, generator):
        sys.stdout.write('GraphObserver:')
        count = generator.get_number()
        for i in range(0, count):
            sys.stdout.write('*')
        print('')
        try:
            time.sleep(1)
        except InterruptedError:
            pass

La classe GraphObserver est également une classe qui implémente l'interface Observer. Cette classe représente le nombre d'observations dans un "graphique simple" comme *****.

main.py


from digit_observer import DigitObserver
from graph_observer import GraphObserver
from random_number_generator import RandomNumberGenerator


def main():
    generator = RandomNumberGenerator()
    observer1 = DigitObserver()
    observer2 = GraphObserver()
    generator.add_observer(observer1)
    generator.add_observer(observer2)
    generator.execute()


if __name__ == "__main__":
    main()

Créez une instance de RandomNumberGenerator et deux observateurs de celui-ci. observer1 est une instance de DigitObserver et observer2 est une instance de GraphObserver.

Après avoir enregistré l'observateur à l'aide de la méthode add_observer, utilisez generator.execute pour générer le nombre.

Résultat d'exécution

DigitObserver:17
GraphObserver:*****************
DigitObserver:43
GraphObserver:*******************************************
DigitObserver:47
GraphObserver:***********************************************
DigitObserver:34
GraphObserver:**********************************
DigitObserver:30
GraphObserver:******************************
DigitObserver:50
GraphObserver:**************************************************
DigitObserver:7
GraphObserver:*******
DigitObserver:40
GraphObserver:****************************************
DigitObserver:39
GraphObserver:***************************************
DigitObserver:41
GraphObserver:*****************************************
DigitObserver:38
GraphObserver:**************************************
DigitObserver:3
GraphObserver:***
DigitObserver:22
GraphObserver:**********************
DigitObserver:26
GraphObserver:**************************
DigitObserver:0
GraphObserver:
DigitObserver:23
GraphObserver:***********************

Résumé

Un objet a été surveillé en ajoutant une méthode qui enregistre l'autre objet (observateur). L'objet surveillé envoie un message à l'observateur enregistré lorsqu'il change.

La manière dont l'observateur gère ces informations n'est pas pertinente pour l'objet surveillé et peut être n'importe quelle classe d'objets.

Les objets ne comprennent pas nécessairement la raison, et par conséquent, la dépendance entre les objets peut être réduite, et l'observateur gère la destination de notification de sorte que la cible d'observation n'ait pas besoin d'être consciente du côté notification.

référence

Recommended Posts

Modèle de conception #Observer
Modèle de conception #Builder
Modèle de conception #Adapter
Modèle de conception #Decorator
Modèle de conception #Facade
Modèle de conception #Strategy
Modèle de conception #Singleton
Modèle de conception #Proxy
Apprenez le modèle de conception "Observer" en Python
[Gang of Four] Apprentissage des modèles de conception --Observer
Modèle d'observateur en Java
Design Pattern #Factory, méthode
Design Pattern #Template, méthode
Modèle de conception Oreore: variable glocale
Python Design Pattern - Méthode de modèle
Modèle d'observateur compris par Nyanko Partie 1
Modèle d'observateur qui peut être vu dans Nyanko Partie 2
Résumé du modèle de conception Java GoF
Apprenez le modèle de conception "Prototype" avec Python
Apprenez le modèle de conception "Builder" avec Python
[Gang of Four] Apprentissage des modèles de conception --Singleton
[Gang of Four] Apprentissage des modèles de conception - Décorateur
[Gang of Four] Apprentissage des modèles de conception - Visiteur
Modèle de conception-Adaptateur
[Gang of Four] Apprentissage des modèles de conception - Médiateur
Apprenez le modèle de conception "Flyweight" en Python
Apprenez le modèle de conception "Memento" avec Python
Apprenez le modèle de conception "Proxy" en Python
Apprenez le modèle de conception "Commande" en Python
[Gang of Four] Apprentissage des modèles de conception - Itérateur
Modèle de conception du GoF à partir du problème 2. Structure
Apprenez le modèle de conception "Visiteur" avec Python
Apprenez le modèle de conception "Bridge" avec Python
Apprenez le modèle de conception "Mediator" avec Python
Apprenez le modèle de conception "Décorateur" avec Python
Modèle de conception-Itérateur
[Gang of Four] Apprentissage des modèles de conception - Façade
[Gang of Four] Apprentissage des modèles de conception - Composite
[Gang of Four] Apprentissage des modèles de conception - Prototype
Modèle de conception du GoF à partir du problème 1. Génération
Apprenez le modèle de conception "Iterator" avec Python
[Gang of Four] Apprentissage des modèles de conception --Mémento
[Gang of Four] Apprentissage des modèles de conception - État
[Gang of Four] Apprentissage des modèles de conception - Interprétation
[Gang of Four] Apprentissage des modèles de conception - Constructeur
Apprenez le modèle de conception «Stratégie» avec Python
[Gang of Four] Apprentissage des modèles de conception - Pont
Apprenez le modèle de conception "Composite" avec Python
Apprenez le modèle de conception "Singleton" avec Python
Apprenez le modèle de conception "État" en Python
Apprenez le modèle de conception "Adapter" avec Python
[Gang of Four] Apprentissage des modèles de conception - Proxy
[Gang of Four] Apprentissage des modèles de conception - Stratégie
[Gang of Four] Apprentissage des modèles de conception - Adaptateur
Apprenez le modèle de conception "Façade" avec Python
[Gang of Four] Apprentissage des modèles de conception - Commande
Modèle de conception GoF à partir du problème 3. Comportement
J'ai étudié les modèles de conception (mémo personnel) Partie 7 (modèle d'observateur, modèle de souvenir, modèle d'état, modèle de poids mouche)
[Gang of Four] Apprentissage des modèles de conception - Poids du vol
[Gang of Four] Apprentissage des modèles de conception - Usine abstraite
Apprenez le modèle de conception "Méthode de modèle" en Python