Betrachten Sie eine Geschenkbox für ein gemeinsames Spiel.
Artikelname | Grund für den Erwerb | Frist für den Erhalt |
---|---|---|
Heilkräuter x 10 | Es ist eine klare Belohnung für Dungeon 4 | Noch 100 Tage |
Magischer Stein | 4. Tag Login Bonus | Noch 100 Tage |
10000 Gold | 6. Tag Login Bonus | Noch 99 Tage |
Heilkräuter x 5 | Es ist eine klare Belohnung für Dungeon 3 | Noch 99 Tage |
5000 Gold | Login-Bonus für den 3. Tag | Noch 96 Tage |
Krieger Kita | Dies ist der Login-Bonus für den ersten Tag | Noch 93 Tage |
Ist das Schema dieser Datenbank so?
Gegenstände, Geld usw. werden nach item_type unterschieden. Nehmen wir an, dass dies der Fall ist.
item_type | Inhalt |
---|---|
1 | Geld |
2 | Artikel |
3 | Charakter |
4 | Magischer Stein |
Wie lautet der Code, wenn ich diesen erhalte (wenn ich ihn aus der aktuellen Box auf meine Hand ziehe)?
def acquire_present(user, present):
if present.item_type == 1:
"""Verarbeitung, um Geld zu erhalten"""
elif present.item_type == 2:
"""Verarbeitung zum Empfang von Artikeln"""
elif present.item_type == 3:
"""Verarbeitung zum Empfangen von Zeichen"""
...
else:
raise Exception()
wenn Satz Hölle. Darüber hinaus besteht eine hohe Wahrscheinlichkeit, dass bei jedem Empfangsprozess verschiedene Aufgaben ausgeführt werden (Handbestätigung, Protokoll usw.). In diesem Fall werden die Funktion purchase_present und jede Datenklasse eng miteinander verbunden.
Darüber hinaus wird es noch länger dauern, wenn item_type aufgrund zukünftiger Spielerweiterungen zunimmt. Lange, wenn Aussagen und enge Kopplungen nicht einfach zu pflegen sind, möchte ich etwas dagegen tun.
Stellen Sie sich daher eine Klasse vor, die den Prozess des Empfangens von Geschenken delegiert.
class AqruireDalegatorBase(object):
"""Basisklasse für Verarbeitungsdelegierung empfangen"""
@classmethod
def acquire(user, present):
raise NotImplementedError()
Sie haben eine gemeinsame Schnittstelle für den Empfang definiert. Erben und implementieren Sie jede empfangende Verarbeitungsdelegationsklasse.
class MoneyAqruireDalegator(AqruireDalegatorBase):
"""Delegationsklasse für die Verarbeitung von Geldbelegen"""
@classmethod
def acquire(user, present):
user.add_money(present.item_quantity)
class ItemAqruireDalegator(AqruireDalegatorBase):
"""Delegierungsklasse für die Verarbeitung von Artikelbelegen"""
@classmethod
def acquire(user, present):
user.add_item(present.item_id, present.item_quantity)
...Folgen Sie anderen
Lassen Sie es uns tatsächlich in die Empfangsfunktion integrieren.
def acquire_present(user, present):
if present.type == 1:
MoneyAqruireDalegator.acquire(user, present)
elif present.type == 2:
ItemAqruireDalegator.acquire(user, present)
elif ...
Durch Ausschneiden der zu empfangenden Logik für jeden Typ entstand das Gefühl einer losen Kopplung!
Aber die if-Anweisung ist immer noch lang und ich muss diese Funktion jedes Mal ändern, wenn ein Typ hinzugefügt wird
DELEGATOR_MAP = {
1: MoneyAqruireDalegator,
2: ItemAqruireDalegator,
...
}
Und Typ- und Delegierungsklassenzuordnung.
def acquire_present(user, present):
delegator_class = DELEGATOR.get(present.item_type)
delegator_class.acquire_present(user, present)
Es ist viel kürzer! Und selbst wenn dies die Typen erhöht
Es ist erweiterbar mit. Die Funktion purchase_present muss nicht geändert werden! Alles was Sie tun müssen, ist die Delegationsklasse mit dem hinzugefügten Test!
Eine lange if-Aussage ist sowohl bei der Untersuchung von Fehlern als auch bei der Erweiterung problematisch. Wenn sie sich also lose gekoppelt anfühlt, ist sie jetzt und in Zukunft freundlich zu den Menschen!
(Ist das ein Fassadenmuster ...? Es fühlt sich ein bisschen wie DI an)
Recommended Posts