[PYTHON] Entwurfsmuster #Proxy

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

Dieses Mal bezog sich das Muster Proxy auf die Struktur.

Was ist Proxy?

Bereiten Sie einen Proxy vor, um die Erstellung von Instanzen und Zugriffsbeschränkungen zu steuern, und lassen Sie den Proxy die Arbeit ausführen, bis sie benötigt wird. Wenn der Agent jedoch den möglichen Bereich überschreitet, gibt der Agent der ursprünglichen Person die Rolle.

Überblick

Dieses Beispielprogramm ist ein "benannter Drucker". Die Hauptklasse erstellt eine Klasseninstanz (Agent) für PrinterProxy. Nennen Sie die Instanz "Alice" und zeigen Sie den Namen an. Benennen Sie es dann in "Bob" um und zeigen Sie diesen Namen an.

Durch Festlegen oder Abrufen des Namens haben wir noch keine Instanz (Person) der realen Druckerklasse erstellt. Die PrinterProxy-Klasse übernimmt das Festlegen und Abrufen des Namens. Schließlich erstellt die PrinterProxy-Klasse nur dann eine Instanz der Printer-Klasse, wenn es Zeit ist, die my_print-Methode tatsächlich aufzurufen und tatsächlich zu drucken.

Eine Schnittstelle namens Printable ist definiert, um die PrinterProxy-Klasse mit der Printer-Klasse gleichzusetzen. Hier wird das Beispielprogramm unter der Annahme erstellt, dass das Instanziieren der Druckerklasse lange dauert. Um auszudrücken, dass es einige Zeit dauert, rufe ich vom Konstruktor eine Methode namens heavy_job auf und verdiene einige Sekunden als "schwere Verarbeitung".

Gesamtklassendiagramm

クラス図

Sequenzdiagramm

シーケンス図

printer.py


import sys
import time
from printable import Printable


class Printer(Printable):

    def __init__(self, name):
        self.__name = name
        self.__heavy_job('Druckerinstanz({0})Wird generiert'.format(self.__name))

    def set_printer_name(self, name):
        self.__name = name

    def get_printer_name(self):
        return self.__name

    def my_print(self, string):
        print('===' + ' ' + self.__name + ' ' + '===')
        print(string)

    def __heavy_job(self, msg):
        sys.stdout.write(msg)
        for i in range(1, 5):
            try:
                time.sleep(1)
            except InterruptedError:
                pass
            sys.stdout.write('.')
        print('Erledigt.')

Die Druckerklasse ist eine Klasse, die "die Person" darstellt. Ich mache Heavy_job als "Heavy Job". Danach gibt es set_printer_name zum Festlegen des Namens, get_printer_name zum Abrufen des Namens und my_print zum Anzeigen der Zeichenfolge. Das Zentrum des Proxy-Musters befindet sich in Richtung der PrinterProxy-Klasse.

printable.py


from abc import abstractmethod


class Printable():

    @abstractmethod
    def set_printer_name(self, name):
        pass

    @abstractmethod
    def get_printer_name(self):
        pass

    @abstractmethod
    def my_printer(self, string):
        pass

Die druckbare Oberfläche dient zum Gleichsetzen der PrinterProxy-Klasse mit der Printer-Klasse.

printer_proxy.py


from printable import Printable
from printer import Printer


class PrinterProxy(Printable):

    def __init__(self, name):
        self.__name = name
        self.__real = None

    def set_printer_name(self, name):
        if (self.__real is not None):
            self.__real.set_printer_name(name)
        self.__name = name

    def get_printer_name(self):
        return self.__name

    def my_print(self, string):
        self.__realize()
        self.__real.my_print(string)

    def __realize(self):
        if (self.__real is None):
            self.__real = Printer(self.__name)

Die PrinterProxy-Klasse fungiert als Agent. Implementiert die druckbare Oberfläche. Das Namensfeld dient zum Halten des Namens und das reale Feld zum Halten der "Person".

Legen Sie im Konstruktor den Namen fest. Die Methode set_printer_name legt einen neuen Namen fest. Wenn real nicht None ist, legen Sie auch den Namen für die Person fest. Wenn real jedoch None ist, wird ein Wert im Feld PrinterProxy name zurückgegeben.

Da die my_print-Methode ein Prozess außerhalb des Bereichs dieses Agenten ist, rufen Sie die Realisierungsmethode auf, um die "Person" zu generieren. Nach dem Ausführen der Realisierungsmethode enthält das reale Feld die Person. Rufen Sie also real.print auf. Dies ist "Delegation".

** Unabhängig davon, wie oft Sie set_printer_name oder get_printer_name aufrufen, wird der Drucker nicht instanziiert. Es wird keine Druckerinstanz erstellt. ** Eine Druckerinstanz wird nur erstellt, wenn die "Person" benötigt wird. (PrinterProxy-Benutzer wissen überhaupt nicht, ob die Person generiert wurde, und es besteht kein Grund zur Sorge.)

Die Realisierungsmethode erstellt eine Instanz von Printer, wenn das reale Feld None ist. Wenn das reale Feld nicht None ist, tun Sie nichts.

main.py


from printer_proxy import PrinterProxy


def main():
    pp = PrinterProxy('Alice')
    print('Der Name ist jetzt' + pp.get_printer_name() + 'ist.')
    pp.set_printer_name('Bob')
    print('Der Name ist jetzt' + pp.get_printer_name() + 'ist.')
    pp.my_print('Hello, world.')

if __name__ == '__main__':
    main()

Ausführungsergebnis

Der Name ist jetzt Alice.
Der Name ist jetzt Bob.
Druckerinstanz(Bob)Wird generiert....Erledigt.
=== Bob ===
Hello, world.

Zusammenfassung

Im Proxy-Muster fungiert die Proxy-Rolle als Agent und übernimmt die Verarbeitung so weit wie möglich. Im Beispielprogramm war es mithilfe der Proxy-Rolle möglich, die Verarbeitung (Instanziierung) bis zum eigentlichen my_print zu verzögern.

Wenn es viele Funktionen gibt, deren Initialisierung in der tatsächlichen Nutzungsszene lange dauert, werden sie meiner Meinung nach nur dann initialisiert, wenn es Zeit ist, diese Funktionen tatsächlich zu verwenden. Ich denke, es ist eines der am häufigsten verwendeten Designmuster.

Referenz

Recommended Posts

Entwurfsmuster #Proxy
Entwurfsmuster #Adapter
Entwurfsmuster #Decorator
Entwurfsmuster #Observer
Entwurfsmuster #Facade
Entwurfsmuster #Strategie
Entwurfsmuster #Singleton
Lernen Sie das Entwurfsmuster "Proxy" in Python
[Viererbande] Designmuster lernen --Proxy
Entwurfsmuster #Factory-Methode
Entwurfsmuster # Template-Methode
Proxy-Muster in Java
Oreore-Entwurfsmuster: Glokale Variable
Python Design Pattern - Template-Methode
[Viererbande] Designmuster lernen
Grobe Zusammenfassung des GoF-Java-Entwurfsmusters
Lernen Sie das Entwurfsmuster "Prototype" mit Python
[Viererbande] Design Pattern Learning - Singleton
[Viererbande] Design Pattern Learning --Decorator
[Viererbande] Designmuster lernen --Besucher
[Viererbande] Design Pattern Learning - Vermittler
Lernen Sie das Designmuster "Flyweight" in Python
Lernen Sie das Entwurfsmuster "Memento" mit Python
Lernen Sie das Entwurfsmuster "Befehl" in Python
[Viererbande] Designmusterlernen --Iterator
Lernen Sie das Entwurfsmuster "Besucher" 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
Ich habe über Entwurfsmuster (persönliches Memo) Teil 8 (Proxy-Muster, Befehlsmuster, Interpreter-Muster) studiert.
[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 "Singleton" mit Python
Lernen Sie das Entwurfsmuster "State" in Python
Lernen Sie das Entwurfsmuster "Adapter" mit Python
[Viererbande] Design Pattern Learning - Strategie
[Viererbande] Designmuster lernen --Adapter
Lernen Sie das Designmuster "Facade" mit Python
[Viererbande] Design Pattern Learning - Beobachter
[Viererbande] Designmuster lernen - Befehl
GoF-Entwurfsmuster aus dem Problem 3. Verhalten
[Viererbande] Designmuster lernen - Fluggewicht
[Viererbande] Designmusterlernen - Abstract Factory
Lernen Sie das Entwurfsmuster "Abstract Factory" mit Python
Lernen Sie das Entwurfsmuster "Vorlagenmethode" in Python
[Viererbande] Designmuster lernen - Fabrikmethode
Lernen Sie das Entwurfsmuster "Factory Method" in Python
[Viererbande] Designmuster lernen - Kette der Verantwortung
[Viererbande] Design Pattern Learning - Template-Methode