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.
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.
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.
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.
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:***********************
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.
Recommended Posts