[GO] Lernen Sie das Entwurfsmuster "Chain of Responsibility" in Python

Als Material zum Erlernen von GoF-Entwurfsmustern scheint das Buch "Einführung in Entwurfsmuster, die in der erweiterten und überarbeiteten Java-Sprache gelernt wurden" hilfreich zu sein. Da die aufgeführten Beispiele jedoch auf JAVA basieren, habe ich dieselbe Vorgehensweise mit Python versucht, um mein Verständnis zu vertiefen.

■ Verantwortungskette (Muster der Verantwortungskette)

Das englische Wort "Chain of Responsibility" bedeutet "Chain of Responsibility". Dieses Muster erstellt eine Kettenbeziehung zwischen mehreren Objekten, für die eine Anforderung empfangen werden soll, und empfängt nacheinander Anforderungen entlang der erstellten Kettenbeziehung, bis es ein Objekt erreicht, das die Anforderung verarbeiten kann. Es ist ein Muster zu gehen. Durch Anwenden dieses Musters muss die Benutzerseite die Befehlsturmrolle (Verbindung) wie "Diese Anforderung wird von diesem Objekt verarbeitet" und die Benutzerseite "auf ein Objekt in einer Kettenbeziehung" nicht kennen. Die Aufteilung der Rollen ist klar: "Wirf einfach eine Anfrage" und die Verarbeitungsseite "verarbeitet die eingehende Anfrage, wenn sie selbst verarbeitet werden kann, und wenn dies nicht möglich ist, übergebe die Anfrage einfach an das nächste Objekt". (Der Benutzer muss die Details des Prozesses nicht kennen.)

UML class and sequence diagram W3sDesign_Chain_of_Responsibility_Design_Pattern_UML.jpg UML class diagram designpattern-chain_of_responsibility01.gif (Das Obige wird aus der "Website für technischen Support für IT-Ingenieure von IT Senka" zitiert)

□ Memorandum

Das Muster "Chain of Responsibility" erinnert an den altmodischen "Arbeitsstil" im Bürostil. Anfragen kommen an Menschen. Wenn die Person damit umgehen kann, tun Sie es. Wenn es nicht verarbeitet werden kann, leitet es die Anfrage an die "nächste Person" weiter. Wenn die nächste Person damit umgehen kann, tun Sie es. Wenn es nicht verarbeitet werden kann, wird die Anfrage an "die nächste Person" weitergeleitet. Ich habe das Muster der "Kette der Verantwortung" als ein sogenanntes lineares listenartiges Verarbeitungsmodell verstanden.

Chain_of_responsibility.png

■ Beispielprogramm "Chain of Responsibility"

Eigentlich möchte ich ein Beispielprogramm ausführen, das das Muster der Verantwortungskette verwendet, und das folgende Verhalten überprüfen.

――Zu der für die Fehlerbehebung erforderlichen Angelegenheit weisen Sie eine "Störungsnummer" zu und lösen Sie das Problem gemäß dem folgenden Arbeitsablauf zur Fehlerbehebung.

<Fehlerbehebung beim Geschäftsablauf> (1) Legen Sie die Reihenfolge des Drehens der Wannen im Voraus fest ("Alice" -> "Bob" -> "Charlie" -> "Diana" -> "Elmo" -> "Fred"). (2) Zunächst akzeptiert "Alice" die Anforderung zur Fehlerbehebung. Alice ist eine ** nicht unterstützte ** Rolle, daher wird die Anfrage an den nächsten Bod weitergeleitet (3) "Bod" nimmt die Anfrage an. "Bod" ist die Rolle des ** eingeschränkten Supports (Obergrenze der Trouble-Nummer "100") **, und wir werden unser Bestes in dieser Rolle geben und das Geschäft beenden, wenn wir es lösen können. Wenn es nicht gelöst werden kann, leiten Sie die Anfrage an den nächsten "Charlie" weiter (4) "Charlie" nimmt die Anfrage an. Charlie ist die Rolle des ** speziellen Supports (Trouble-Nummer ist nur" 429 ") , und wir werden unser Bestes in dieser Rolle geben und das Geschäft beenden, wenn wir es lösen können. Wenn es nicht gelöst werden kann, leiten Sie die Anfrage an die nächste "Diana" weiter (5) "Diana" nimmt die Anfrage an. Diana ist die Rolle des ** eingeschränkten Supports (Obergrenze der Trouble-Nummer" 200 "), und wir werden unser Bestes in dieser Rolle geben und das Geschäft beenden, wenn wir es lösen können. Wenn es nicht gelöst werden kann, leiten Sie die Anfrage an den nächsten "Elmo" weiter (6) "Elmo" nimmt die Anfrage an. Elmo hat die Rolle, ** nur ungerade Zahlen zu unterstützen ** und wird innerhalb dieses Rollenbereichs sein Bestes geben. Wenn es gelöst werden kann, wird das Geschäft beendet. Wenn es nicht gelöst werden kann, leiten Sie die Anfrage an den nächsten "Fred" weiter (7) "Fred" nimmt die Anfrage an. Fred ist die Rolle des ** eingeschränkten Supports (Obergrenze der Trouble-Nummer" 300 ") **, und wir werden unser Bestes in dieser Rolle geben und das Geschäft beenden, wenn wir es lösen können. Wenn es nicht gelöst werden kann, endet es schließlich mit "Nicht lösbar".

$ python Main.py 
[Trouble 0] is resolved by [Bob].
[Trouble 33] is resolved by [Bob].
[Trouble 66] is resolved by [Bob].
[Trouble 99] is resolved by [Bob].
[Trouble 132] is resolved by [Diana].
[Trouble 165] is resolved by [Diana].
[Trouble 198] is resolved by [Diana].
[Trouble 231] is resolved by [Elmo].
[Trouble 264] is resolved by [Fred].
[Trouble 297] is resolved by [Elmo].
[Trouble 330] cannot be resolved.
[Trouble 363] is resolved by [Elmo].
[Trouble 396] cannot be resolved.
[Trouble 429] is resolved by [Charlie].
[Trouble 462] cannot be resolved.
[Trouble 495] is resolved by [Elmo].

Irgendwie war das Ausgabeergebnis schwer zu verstehen. Um das Ausgabeergebnis des Beispielprogramms zu verstehen, scheint es schneller zu sein, die Details des Beispielprogramms zu überprüfen.

■ Details zum Beispielprogramm

Ähnlicher Code wurde in das Git-Repository hochgeladen. https://github.com/ttsubo/study_of_design_pattern/tree/master/Chain_of_Responsibility

--Verzeichnisaufbau

.
├── Main.py
├── support.py
└── trouble.py

(1) Die Rolle des Handlers

Die Rolle "Handler" ist die Rolle, die die Schnittstelle für die Verarbeitung von Anforderungen definiert. Behalten Sie die "nächste Person", und wenn Sie eine Anfrage erhalten, die Sie nicht bearbeiten können, können Sie sie an diese Person senden. Natürlich spielt die "nächste Person" auch die Rolle des "Handlers". Im Beispielprogramm übernimmt die Klasse "Support" diese Rolle. Die Methode, die die Anfrage bearbeitet, war die "Support" -Methode.

support.py


from abc import ABCMeta, abstractmethod

class Support(metaclass=ABCMeta):
    def __init__(self, name):
        self.__name = name
        self.__next = None

    def setNext(self, next):
        self.__next = next
        return next

    def support(self, trouble):
        if self.resolve(trouble):
            self.done(trouble)
        elif self.__next is not None:
            self.__next.support(trouble)
        else:
            self.fail(trouble)

    def __str__(self):
        return "[{0}]".format(self.__name)

    @abstractmethod
    def resolve(self, trouble):
        pass

    def done(self, trouble):
        print("{0} is resolved by {1}.".format(trouble, self))

    def fail(self, trouble):
        print("{0} cannot be resolved.".format(trouble))

(2) Die Rolle von ConcreteHandler

Die Rolle "ConcreteHandler" ist eine bestimmte Rolle für die Verarbeitung einer Anforderung. Im Beispielprogramm übernehmen die Klassen "NoSupport", "LimitSupport", "OddSupport" und "SpecialSupport" diese Rolle.

support.py


class NoSupport(Support):
    def __init__(self, name):
        super(NoSupport, self).__init__(name)

    def resolve(self, trouble):
        return False

class LimitSupport(Support):
    def __init__(self, name, limit):
        super(LimitSupport, self).__init__(name)
        self.__limit = limit

    def resolve(self, trouble):
        return True if trouble.getNumber() < self.__limit else False

class OddSupport(Support):
    def __init__(self, name):
        super(OddSupport, self).__init__(name)

    def resolve(self, trouble):
        return True if trouble.getNumber() % 2 == 1 else False

class SpecialSupport(Support):
    def __init__(self, name, number):
        super(SpecialSupport, self).__init__(name)
        self.__number = number

    def resolve(self, trouble):
        return True if trouble.getNumber() == self.__number else False

(3) Die Rolle des Kunden

Die "Client" -Rolle ist die Rolle, die eine Anforderung an die erste "ConcreteHandler" -Rolle stellt. Im Beispielprogramm übernimmt die Methode "startMain" diese Rolle.

Main.py


from support import NoSupport, LimitSupport, SpecialSupport, OddSupport
from trouble import Trouble

def startMain():
    alice = NoSupport("Alice")
    bob = LimitSupport("Bob", 100)
    charlie = SpecialSupport("Charlie", 429)
    diana = LimitSupport("Diana", 200)
    elmo = OddSupport("Elmo")
    fred = LimitSupport("Fred", 300)

    alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred)

    for i in range(0, 500, 33):
        alice.support(Trouble(i))

if __name__ == '__main__':
    startMain()

(4) Andere

Problemnummern zentral verwalten.

trouble.py


class Trouble:
    def __init__(self, number):
        self.__number = number

    def getNumber(self):
        return self.__number

    def __str__(self):
        return '[Trouble {0}]'.format(self.__number)

■ Referenz-URL

Recommended Posts

Lernen Sie das Entwurfsmuster "Chain of Responsibility" in Python
Lernen Sie das Entwurfsmuster "Prototype" mit Python
Lernen Sie das Entwurfsmuster "Builder" mit Python
Lernen Sie das Designmuster "Flyweight" in Python
Lernen Sie das Entwurfsmuster "Observer" in Python
Lernen Sie das Entwurfsmuster "Memento" mit Python
Lernen Sie das Entwurfsmuster "Proxy" in Python
Lernen Sie das Entwurfsmuster "Befehl" in Python
Lernen Sie das Entwurfsmuster "Bridge" mit Python
Lernen Sie das Entwurfsmuster "Mediator" mit Python
Lernen Sie das Entwurfsmuster "Iterator" mit Python
Lernen Sie das Entwurfsmuster "Strategie" mit Python
Lernen Sie das Entwurfsmuster "Composite" mit Python
Lernen Sie das Entwurfsmuster "State" in Python
Lernen Sie das Entwurfsmuster "Adapter" mit Python
Lernen Sie das Entwurfsmuster "Abstract Factory" mit Python
Lernen Sie das Entwurfsmuster "Vorlagenmethode" in Python
Muster der Verantwortungskette in Java
Lernen Sie das Entwurfsmuster "Singleton" mit Python
Lernen Sie das Designmuster "Facade" mit Python
[Viererbande] Designmuster lernen - Kette der Verantwortung
Implementieren Sie das Singleton-Muster in Python
Lernen Sie die Grundlagen von Python ① Grundlegende Anfänger
Überprüfen Sie das Verhalten des Zerstörers in Python
Das Ergebnis der Installation von Python auf Anaconda
Grundlagen zum Ausführen von NoxPlayer in Python
Auf der Suche nach dem schnellsten FizzBuzz in Python
Lernen Sie intuitiv die Umformung von Python np
Geben Sie die Anzahl der CPU-Kerne in Python aus
[Python] Sortieren Sie die Liste von pathlib.Path in natürlicher Reihenfolge
Holen Sie sich den Aufrufer einer Funktion in Python
Passen Sie die Verteilung jeder Gruppe in Python an
Zeigen Sie das Ergebnis der Geometrieverarbeitung in Python an
Kopieren Sie die Liste in Python
Finden Sie die Lösung der Gleichung n-ter Ordnung mit Python
Die Geschichte des Lesens von HSPICE-Daten in Python
[Hinweis] Über die Rolle des Unterstrichs "_" in Python
Lösen von Bewegungsgleichungen in Python (odeint)
Ausgabe in Form eines Python-Arrays
Singleton-Muster in Python
Besuchermuster in Python
Erleben Sie die gute Berechnungseffizienz der Vektorisierung in Python
Lerne Nim mit Python (ab Anfang des Jahres).
[Python] Ruft die Liste der im Modul definierten Klassen ab
Die Geschichte von FileNotFound im Python open () -Modus = 'w'
Implementieren Sie die Lösung der Riccati-Algebra in Python
Ermitteln Sie die Größe (Anzahl der Elemente) von Union Find in Python
Den Inhalt der Daten in Python nicht kennen
Reproduzieren Sie das Ausführungsbeispiel von Kapitel 4 von Hajipata in Python
Verwenden wir die offenen Daten von "Mamebus" in Python
Implementierte den Algorithmus von "Algorithm Picture Book" in Python3 (Heap Sort Edition)
[Python] Gibt alle Kombinationen von Elementen in der Liste aus
Rufen Sie die URL des HTTP-Umleitungsziels in Python ab
Ein Memorandum über die Umsetzung von Empfehlungen in Python
Reproduzieren Sie das Ausführungsbeispiel von Kapitel 5 von Hajipata in Python
Um das Äquivalent von Rubys ObjectSpace._id2ref in Python zu tun
Überprüfen Sie die atrophische Natur der Wahrscheinlichkeitsverteilung in Python
Ich habe über Designmuster (persönliches Memo) Teil 6 (Muster der Verantwortungskette, Fassadenmuster, Vermittlermuster) studiert.
Auf dem Weg zum Ruhestand von Python2