[PYTHON] Design, das den Verbindungsgrad mit if-Anweisungen auf der Serverseite von Soshage verringern kann

Gemeinsamer Anblick

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? スクリーンショット 2016-12-02 18.53.56.png

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.

Trennung des Empfangsprozesses

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!

Versuchen Sie, die Erweiterung zu vereinfachen

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

  1. Implementieren Sie eine empfangende Delegierungsklasse, die von AqruireDalegatorBase erbt
  2. Fügen Sie DELEGATOR_MAP hinzu

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!

Zusammenfassung (?)

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

Design, das den Verbindungsgrad mit if-Anweisungen auf der Serverseite von Soshage verringern kann
Ermitteln Sie mit Selenium + PhantomJS + Python die Breite des Div auf der Serverseite
Dies und das der Einschlussnotation.
Stellen Sie die Farbe auf der Posterseite so ein, dass sich die Farbe des Youtube-Untertitels automatisch ändert.
Zeichentipps mit matplotlib auf der Serverseite
Zusammenfassung der Versionen der Standard-Python-Bibliothek, die jetzt auf https vom Server validiert werden