[GO] Lernen Sie das Entwurfsmuster "Memento" mit 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.

■ Memento (Memento-Muster)

Das englische Wort "Memento" bedeutet "Andenken / Denkmal". Dieses Muster ist ein Muster, das ein Gerät bereitstellt, um den Status eines Objekts zu jedem Zeitpunkt zu speichern (zu speichern) und das Objekt später in diesen Status zurückzusetzen. (Der Zustand kann wiederhergestellt werden, ohne die Kapselung zu unterbrechen.) Mit anderen Worten, ein Muster zum Bereitstellen der in Texteditoren usw. implementierten Funktion "Rückgängig" (Vorgang abbrechen und in den Zustand vor dem Vorgang zurückkehren). ist. Es ist zu beachten, dass nur die minimal erforderlichen Informationen (Feldwert) zum Wiederherstellen des Status gespeichert werden. (Das oben Genannte wird aus der "Website für technischen Support für IT-Ingenieure von IT Senka" zitiert)

UML class and sequence diagram W3sDesign_Memento_Design_Pattern_UML.jpg (Das Obige wird aus Wikipedia zitiert)

■ Beispielprogramm "Memento"

Eigentlich möchte ich ein Beispielprogramm ausführen, das das Memento-Muster verwendet, und das folgende Verhalten überprüfen. Zusätzlich übernimmt das Beispielprogramm ** "Würfelspiel zum Sammeln von Früchten" ** die folgenden Operationen.


Bewegung nach den Augen der Würfel

  1. Wenn der Würfelwurf "1" </ font> ist, erhöht sich Ihr Geld um ** 100 Yen **
  2. Wenn der Würfelwurf "2" </ font> ist, beträgt der Geldbetrag ** die Hälfte ** (Brüche werden abgerundet).
  3. Wenn der Würfel "6" </ font> würfelt, erhalten Sie ** Obst ** (Sie können normale ** "Früchte" ** bekommen, aber Sie können ** "leckere Früchte" ** bekommen, die Wahrscheinlichkeit beträgt 50%)
  4. Wenn andere Würfel würfeln, passiert nichts
$ python Main.py 
==== 0
Aktueller Status:[money = 100, fruits = []]
Ich habe mehr geld
Der Geldbetrag, den ich habe, beträgt jetzt 200 Yen
      (Es hat stark zugenommen, also speichern wir den aktuellen Status)

==== 1
Aktueller Status:[money = 200, fruits = []]
Früchte(Leckere Trauben)ich habe
Der Geldbetrag, den ich habe, beträgt jetzt 200 Yen

==== 2
Aktueller Status:[money = 200, fruits = ['Leckere Trauben']]
Nichts ist passiert
Der Geldbetrag, den ich habe, beträgt jetzt 200 Yen

==== 3
Aktueller Status:[money = 200, fruits = ['Leckere Trauben']]
Ich habe mehr geld
Der Geldbetrag, den ich habe, beträgt jetzt 300 Yen
      (Es hat stark zugenommen, also speichern wir den aktuellen Status)


...(snip)


==== 22
Aktueller Status:[money = 500, fruits = ['Leckere Trauben', 'Leckere Trauben', 'Leckere Banane', 'Köstlicher Apfel', 'Apfel', 'Banane']]
Früchte(Leckere Banane)ich habe
Der Geldbetrag, den ich habe, beträgt jetzt 500 Yen

==== 23
Aktueller Status:[money = 500, fruits = ['Leckere Trauben', 'Leckere Trauben', 'Leckere Banane', 'Köstlicher Apfel', 'Apfel', 'Banane', 'Leckere Banane']]
Ich habe mehr geld
Der Geldbetrag, den ich habe, beträgt jetzt 600 Yen
      (Es hat stark zugenommen, also speichern wir den aktuellen Status)

==== 24
Aktueller Status:[money = 600, fruits = ['Leckere Trauben', 'Leckere Trauben', 'Leckere Banane', 'Köstlicher Apfel', 'Apfel', 'Banane', 'Leckere Banane']]
Der Geldbetrag, den Sie haben, wurde halbiert
Der Geldbetrag, den ich habe, beträgt jetzt 300 Yen

==== 25
Aktueller Status:[money = 300, fruits = ['Leckere Trauben', 'Leckere Trauben', 'Leckere Banane', 'Köstlicher Apfel', 'Apfel', 'Banane', 'Leckere Banane']]
Nichts ist passiert
Der Geldbetrag, den ich habe, beträgt jetzt 300 Yen

==== 26
Aktueller Status:[money = 300, fruits = ['Leckere Trauben', 'Leckere Trauben', 'Leckere Banane', 'Köstlicher Apfel', 'Apfel', 'Banane', 'Leckere Banane']]
Der Geldbetrag, den Sie haben, wurde halbiert
Der Geldbetrag, den ich habe, beträgt jetzt 150 Yen
      (Es hat stark abgenommen, also kehren wir zum vorherigen Zustand zurück)

==== 27
Aktueller Status:[money = 600, fruits = ['Leckere Trauben', 'Leckere Trauben', 'Leckere Banane', 'Köstlicher Apfel', 'Leckere Banane']]
Der Geldbetrag, den Sie haben, wurde halbiert
Der Geldbetrag, den ich habe, beträgt jetzt 300 Yen

...(snip)

Am Ende konnte ich den Vorgang mit dem Memento-Muster bestätigen.

■ Details zum Beispielprogramm

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

--Verzeichnisaufbau

.
├── Main.py
└── memento
    ├── __init__.py
    ├── gamer.py
    └── memento.py

(1) Die Rolle des Urhebers

Die Rolle "Urheber" erstellt eine "Erinnerungsrolle", wenn Sie Ihren aktuellen Status speichern möchten. Die "Originator" -Rolle kehrt auch nach Übergabe der vorherigen "Memento" -Rolle in den Zustand zurück, in dem sie sich befand, als die "Memento" -Rolle erstellt wurde. Im Beispielprogramm übernimmt die Klasse "Gamer" diese Rolle.

memento/gamer.py


import random
from memento.memento import Memento

class Gamer(object):
    def __init__(self, money):
        self.__fruitname = ["Apfel", "Traube", "Banane", "Mandarine"]
        self.__money = money
        self.__fruits = []

    def getMoney(self):
        return self.__money

    def bet(self):
        dice = random.randint(1, 6)
        if dice == 1:
            self.__money += 100
            print("Ich habe mehr geld")
        elif dice == 2:
            self.__money //= 2
            print("Der Geldbetrag, den Sie haben, wurde halbiert")
        elif dice == 6:
            f = self.__getFruit()
            print("Früchte({0})ich habe".format(f))
            self.__fruits.append(f)
        else:
            print("Nichts ist passiert")

    def createMemento(self):
        m = Memento(self.__money)
        for f in self.__fruits:
            if f.startswith("Köstlich"):
                m.addFruit(f)
        return m

    def restoreMemento(self, memento):
        self.__money = memento.money
        self.__fruits = memento.getFruits()

    def __str__(self):
        return "[money = {0}, fruits = {1}]".format(self.__money, self.__fruits)

    def __getFruit(self):
        prefix = ''
        if bool(random.getrandbits(1)):
            prefix = "Köstlich"
        return prefix + random.choice(self.__fruitname)

(2) Die Rolle von Memento (Souvenir)

Die Rolle "Andenken" fasst die internen Informationen der Rolle "Urheber" zusammen. Die Rolle "Andenken" enthält interne Informationen über die Rolle "Urheber", diese Informationen werden jedoch nicht an alle weitergegeben. Im Beispielprogramm übernimmt die Klasse "Memento" diese Rolle.

memento/memento.py


class Memento(object):
    def __init__(self, money):
        self.money = money
        self.fruits = []

    def getMoney(self):
        return self.money

    def addFruit(self, fruit):
        self.fruits.append(fruit)

    def getFruits(self):
        return self.fruits

(3) Die Rolle des Hausmeisters

Die Rolle "Hausmeister" teilt der Rolle "Urheber" mit, wann Sie den aktuellen Status der Rolle "Urheber" speichern möchten. Die Rolle "Urheber" empfängt sie, erstellt eine "Erinnerungsrolle" und übergibt sie an die Rolle "Hausmeister". Die Rolle "Hausmeister" speichert die Rolle "Erinnerungsstück" für zukünftige Anforderungen. Im Beispielprogramm übernimmt die Methode "startMain" diese Rolle.

Main.py


import time
from memento.gamer import Gamer

def startMain():
    gamer = Gamer(100)
    memento = gamer.createMemento()

    for i in range(100):
        print("==== {0}".format(i))
        print("Aktueller Status:{0}".format(gamer))
        gamer.bet()
        print("Das Geld, das du hast{0}Es wurde ein Kreis".format(gamer.getMoney()))

        if gamer.getMoney() > memento.getMoney():
            print("      (Es hat stark zugenommen, also speichern wir den aktuellen Status)")
            memento = gamer.createMemento()
        elif gamer.getMoney() < memento.getMoney() / 2:
            print("      (Es hat stark abgenommen, also kehren wir zum vorherigen Zustand zurück)")
            gamer.restoreMemento(memento)

        time.sleep(1)
        print("")

if __name__ == '__main__':
    startMain()

■ Referenz-URL

Recommended Posts