[PYTHON] Entwurfsmuster #Observer

Ich habe Designmuster geübt, um Code zu schreiben, der sich des Designs bewusst war. Andere Entwurfsmuster werden häufig veröffentlicht.

Vorwort

Das Hauptziel ist zu verstehen, wann, was und wie Entwurfsmuster verwendet werden. (Ich bin neu in Java oder einer statisch typisierten Sprache und habe keine lange Geschichte mit Python. Ich denke, es gibt einige Dinge, die Pythonista nicht ähneln. Wenn Sie Vorschläge haben, bringen Sie mir dies bitte bei.)

Diesmal ist das Muster Beobachter bezüglich des Verhaltens.

Was ist Beobachter?

Im Beobachtermuster wird der Beobachter benachrichtigt, wenn sich der Zustand des Beobachtungsziels ändert. Das Observer-Muster ist nützlich, wenn Sie die Verarbeitung beschreiben, die auf Statusänderungen reagiert.

Überblick

Mit dem hier erstellten Beispielprogramm kann der Beobachter ein Objekt beobachten, das eine große Zahl generiert, und seinen Wert anzeigen. Die Anzeigemethode unterscheidet sich jedoch je nach Beobachter. DigitObserver zeigt die Werte numerisch an, während GraphObserver die Werte in einem einfachen Diagramm anzeigt.

Gesamtklassendiagramm

observer.py


from abc import ABCMeta, abstractmethod


class Observer(Exception):
    __meta__ = ABCMeta

    @abstractmethod
    def update(self, generator):
        pass

Die Beobachterschnittstelle ist eine Schnittstelle, die einen "Beobachter" ausdrückt. Bestimmte Beobachter implementieren diese Schnittstelle.

Es ist der NumberGenerator, der die Nummer generiert, die die Aktualisierungsmethode aufruft. Die Aktualisierungsmethode ist eine Methode, mit der NumberGenerator dem Beobachter mitteilt, dass "Mein Inhalt aktualisiert wurde. Bitte aktualisieren Sie auch die Anzeige."

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

Die NumberGenerator-Klasse ist eine abstrakte Klasse, die Zahlen generiert. Die eigentliche Zahlengenerierung (Ausführungsmethode) und der Teil zum Abrufen der Zahl (Methode get_number) sind abstrakte Methoden, die voraussichtlich von der Unterklasse implementiert werden.

Das Beobachterfeld ist das Feld, in dem die Beobachter gespeichert sind, die den Zahlengenerator beobachten.

add_observer ist eine Methode zum Hinzufügen eines Beobachters, und delete_observer ist eine Methode zum Löschen eines Beobachters.

Die Methode notify_observers teilt allen Beobachtern mit: "Mein Inhalt wurde aktualisiert. Bitte aktualisieren Sie Ihre Anzeige." Bei dieser Methode wird die Aktualisierungsmethode für jeden Beobachter in den Beobachtern aufgerufen.

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

Die RandomNumberGenerator-Klasse ist eine Unterklasse von NumberGenerator, die Zufallszahlen generiert.

Das Zufallsfeld enthält den Zufallszahlengenerator und das Zahlenfeld enthält den aktuellen Zufallswert.

Die Methode get_number gibt den Wert des Zahlenfelds zurück.

Die Methode execute generiert 20 Zufallszahlen (Ganzzahlen von 0 bis 49) und verwendet jedes Mal notify_observers, um den Beobachter zu benachrichtigen.

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)

Die DigitObserver-Klasse ist eine Klasse, die die Beobachterschnittstelle implementiert und verwendet wird, um die Anzahl der Beobachtungen als "Zahl" anzuzeigen. Verwenden Sie die Methode get_number von NumberGenerator, die in der Aktualisierungsmethode als Argument angegeben ist, um die Nummer abzurufen und anzuzeigen. Es gibt Intervalle, in denen Sie sehen können, wie die Anzeige aussieht.

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

Die GraphObserver-Klasse ist auch eine Klasse, die die Observer-Schnittstelle implementiert. Diese Klasse repräsentiert die Anzahl der Beobachtungen in einem "einfachen Graphen" wie *****.

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

Erstellen Sie eine Instanz von RandomNumberGenerator und zwei Beobachter davon. Observer1 ist eine Instanz von DigitObserver und Observer2 ist eine Instanz von GraphObserver.

Verwenden Sie nach der Registrierung des Beobachters mit der Methode add_observer generator.execute, um die Nummer zu generieren.

Ausführungsergebnis

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:***********************

Zusammenfassung

Ein Objekt wurde überwacht, indem eine Methode hinzugefügt wurde, die das andere Objekt (Beobachter) registriert. Das überwachte Objekt sendet eine Nachricht an den registrierten Beobachter, wenn es sich ändert.

Wie der Beobachter mit diesen Informationen umgeht, ist für das überwachte Objekt irrelevant und kann eine beliebige Objektklasse sein.

Objekte verstehen den Grund nicht unbedingt, und infolgedessen kann die Abhängigkeit zwischen Objekten verringert werden, und der Beobachter verwaltet das Benachrichtigungsziel so, dass das Beobachtungsziel die Benachrichtigungsseite nicht kennen muss.

Referenz

Recommended Posts

Entwurfsmuster #Observer
Entwurfsmuster #Builder
Entwurfsmuster #Adapter
Entwurfsmuster #Decorator
Entwurfsmuster #Facade
Entwurfsmuster #Strategie
Entwurfsmuster #Singleton
Entwurfsmuster #Proxy
Lernen Sie das Entwurfsmuster "Observer" in Python
[Viererbande] Design Pattern Learning - Beobachter
Beobachtermuster in Java
Entwurfsmuster #Factory-Methode
Entwurfsmuster # Template-Methode
Oreore-Entwurfsmuster: Glokale Variable
Python Design Pattern - Template-Methode
Beobachtermuster von Nyanko Teil 1 verstanden
Beobachtermuster, das in Nyanko Teil 2 zu sehen ist
Grobe Zusammenfassung des GoF-Java-Entwurfsmusters
Lernen Sie das Entwurfsmuster "Prototype" mit Python
Lernen Sie das Entwurfsmuster "Builder" mit Python
[Viererbande] Design Pattern Learning - Singleton
[Viererbande] Design Pattern Learning --Decorator
[Viererbande] Designmuster lernen --Besucher
Design Muster-Adapter
[Viererbande] Design Pattern Learning - Vermittler
Lernen Sie das Designmuster "Flyweight" in Python
Lernen Sie das Entwurfsmuster "Memento" mit Python
Lernen Sie das Entwurfsmuster "Proxy" in Python
Lernen Sie das Entwurfsmuster "Befehl" in Python
[Viererbande] Designmusterlernen --Iterator
GoF-Entwurfsmuster aus dem Problem 2. Struktur
Lernen Sie das Entwurfsmuster "Besucher" mit Python
Lernen Sie das Entwurfsmuster "Bridge" mit Python
Lernen Sie das Entwurfsmuster "Mediator" mit Python
Lernen Sie das Designmuster "Decorator" mit Python
Design Muster-Iterator
[Viererbande] Designmuster lernen - Fassade
[Viererbande] Design Pattern Learning - Composite
[Viererbande] Designmuster lernen - Prototyp
GoF-Entwurfsmuster aus dem Problem 1. Generation
Lernen Sie das Entwurfsmuster "Iterator" mit Python
[Viererbande] Designmuster lernen - Andenken
[Viererbande] Designmuster lernen - Staat
[Vierergruppe] Design Pattern Learning - Interpreter
[Viererbande] Design Pattern Learning - Builder
Lernen Sie das Entwurfsmuster "Strategie" mit Python
[Viererbande] Designmuster lernen - Brücke
Lernen Sie das Entwurfsmuster "Composite" mit Python
Lernen Sie das Entwurfsmuster "Singleton" mit Python
Lernen Sie das Entwurfsmuster "State" in Python
Lernen Sie das Entwurfsmuster "Adapter" mit Python
[Viererbande] Designmuster lernen --Proxy
[Viererbande] Design Pattern Learning - Strategie
[Viererbande] Designmuster lernen --Adapter
Lernen Sie das Designmuster "Facade" mit Python
[Viererbande] Designmuster lernen - Befehl
GoF-Entwurfsmuster aus dem Problem 3. Verhalten
Ich habe über Designmuster (persönliches Memo) Teil 7 (Beobachtermuster, Erinnerungsmuster, Zustandsmuster, Fliegengewichtsmuster) studiert.
[Viererbande] Designmuster lernen - Fluggewicht
[Viererbande] Designmusterlernen - Abstract Factory
Lernen Sie das Entwurfsmuster "Vorlagenmethode" in Python