Dieser Inhalt ist für Anfänger gedacht, die versuchen möchten, Entwurfsmuster mit Maya Python zu verwenden. Ich werde die ausführliche Erklärung des Entwurfsmusters anderen Websites überlassen. Wie verbessert sich der Code, wenn Sie ihn tatsächlich verwenden? Konzentrieren Sie sich auf. Nehmen Sie als Anwendungsbeispiel so etwas wie einen Datenexporter als Beispiel.
Ich möchte die Entwurfsleistung und die Codequalität verbessern, indem ich tatsächlich Entwurfsmuster verwende. Ich möchte ein Muster finden, das insbesondere bei der Implementierung von Werkzeugen verwendet werden kann.
Dieses Mal wird das folgende Muster verwendet. Einzelheiten zum Muster finden Sie auf der Referenzseite unten auf der Seite.
Muster | Übersicht (meine Wahrnehmung) | verdienen |
---|---|---|
TemplateMethod | Abstrahieren Sie die von der übergeordneten Klasse aufgerufene Methode und überlassen Sie die Implementierung innerhalb der Methode der Unterklasse. | ProzessablaufVon jedem Prozess beim BindenVerhaltenWird der Unterklasse überlassen. |
FactoryMethod | Wenn Sie ein anderes Objekt in der Klasse verwenden, abstrahieren Sie den Generierungsprozess und verwenden Sie das (abstrahierte) Generierungsobjekt. Der Generierungsprozess und die Methodenimplementierung werden jeder Unterklasse überlassen. | Es erbt die Güte der Vorlagenmethode. Beim Erstellen eines anderen Objekts und Aufrufen einer MethodeProzessablauf・Generieren・VerhaltenKann getrennt werden. |
Factory | Bereiten Sie eine Klasse vor und verwenden Sie sie, die nur Objekte unter den angegebenen Bedingungen erstellt. | Von der Seite, die das Objekt verwendet, entspricht das Objekt den BedingungenGenerierenKann getrennt werden. |
Ich dachte, dass der Export von Maya-Szeneninformationen relativ umfangreich ist, also habe ich ihn gewählt. Das Bild ist wie die Ausgabe geeigneter Daten mithilfe des FBX-Exports. Es wird erkannt, dass die Spezifikationen wahrscheinlich später geändert werden, z. B. die Auswahl von Ausgabedaten oder die Durchführung einer speziellen Verarbeitung in Abhängigkeit von den Bedingungen. Es beschreibt, wie der Code vor und nach dem Anwenden des Entwurfsmusters aussehen wird.
Wenn Sie die Prozesse anordnen, ohne über etwas Besonderes nachzudenken, sieht dies wie folgt aus.
scene_exporter.py
def scene_export(option):
"""Ausgabemodelle und Animationen in der Szene"""
#Vorverarbeitung
if option.mode == ExportMode.head:
#Suchen Sie nach Kopfnetzdaten in der Hierarchie
#Etwas tun
#Export
if option.mode == ExportMode.body:
#Suchen Sie nach Body-Mesh-Daten in der Hierarchie
#Etwas tun
#Export
if option.mode == ExportMode.animation:
#Suchen Sie Skelettdaten in der Hierarchie
#Etwas tun
#Export
#Nachbearbeitung
Wenden Sie vorerst das Muster der Vorlagenmethode an, um den Exportprozess zu standardisieren.
exporter.py
from abc import ABCMeta, abstractmethod
class BaseExporter(object):
"""Exporter Grundklasse"""
__metaclass__ = ABCMeta
def export(self):
select_export_targets()
export_selection()
@abstractmethod
def select_export_targets(self):
"""Wählen Sie das Exportziel"""
pass
@abstractmethod
def export_selection(self):
"""Exportieren Sie ausgewählte Objekte"""
pass
class HeadExporter(BaseExporter):
"""Exporteurklasse für HEAD"""
def select_export_targets(self):
cmds.select("|char|mesh|head")
def export_selection(self):
#Implementierte Ausgabeverarbeitung für HEAD
class BodyExporter(BaseExporter):
"""Exporteurklasse für KÖRPER"""
def select_export_targets(self):
cmds.select("|char|mesh|body")
def export_selection(self):
#Implementierte Ausgabeverarbeitung für BODY
class AnimExporter(BaseExporter):
"""Exporterklasse für ANIM"""
def select_export_targets(self):
cmds.select("|char|skel|root")
def export_selection(self):
#Implementierte Ausgabeverarbeitung für ANIM
scene_exporter_v2.py
def scene_export(option):
"""Ausgabemodelle und Animationen in der Szene"""
#Vorverarbeitung
if option.mode == ExportMode.head:
HeadExporter().export()
if option.mode == ExportMode.body:
BodyExporter().export()
if option.mode == ExportMode.animation:
AnimExporter().export()
#Nachbearbeitung
Selbst wenn TemplateMethod angewendet wird, wurde die Wartbarkeit beim Hinzufügen eines Modus noch nicht verbessert. Erstellen Sie eine neue Factory-Klasse und lassen Sie sie verzweigen und generieren. Der Hauptprozess verwendet nur die BaseExporter-Unterklasse, in der export () vorhanden ist.
exporter_factory.py
class BaseExporterFactory(object):
"""Factory-Klasse der BaseExporter-Klasse"""
def create(option):
if option.mode == ExportMode.head:
return HeadExporter()
if option.mode == ExportMode.body:
return BodyExporter()
if option.mode == ExportMode.animation:
return AnimExporter()
scene_exporter_v3.py
def scene_export(option):
"""Ausgabemodelle und Animationen in der Szene"""
#Vorverarbeitung
BaseExporterFactory().create(option).export()
#Nachbearbeitung
Wenn die Spezifikation hinzugefügt wird, erstellen und verwenden wir "ein Protokollobjekt innerhalb der BaseExporter-Klasse". Wenden Sie FactoryMethod an, da Sie Objekte in der BaseExporter-Klasse erstellen und verwenden.
Implementieren Sie das übergeordnete Element und die Unterklassen von ExporterLog, dem Produkt von FactoryMethod.
exporter_log.py
from abc import ABCMeta, abstractmethod
class BaseExporterLog(object):
"""Basisklasse des Exporterprotokolls"""
__metaclass__ = ABCMeta
@abstractmethod
def open(self):
"""Starten Sie die Protokollierung"""
pass
@abstractmethod
def close(self):
"""Protokollierung beenden"""
pass
class MyExporterLog(BaseExporterLog):
"""Unterklasse des Exporterprotokolls"""
def open(self):
print "export logging start"
def close(self):
print "export logging close"
Definieren Sie die Protokollgenerierung und -verwendung in BaseExporter, dem Ersteller von FactoryMethod, und überlassen Sie die Implementierung Unterklassen.
exporter.py
from abc import ABCMeta, abstractmethod
class BaseExporter(object):
"""Exporter Grundklasse"""
__metaclass__ = ABCMeta
def export(self):
self.log = create_exporter_log()
self.log.open()
select_export_targets()
export_selection()
self.log.close()
@abstractmethod
def create_exporter_log(self):
"""Generieren Sie ein Exportprotokoll"""
pass
@abstractmethod
def select_export_targets(self):
"""Wählen Sie das Exportziel"""
pass
@abstractmethod
def export_selection(self):
"""Exportieren Sie ausgewählte Objekte"""
pass
class HeadExporter(BaseExporter):
"""Exporteurklasse für HEAD"""
def create_exporter_log(self):
return MyExporterLog()
def select_export_targets(self):
cmds.select("|char|mesh|head")
def export_selection(self):
#Implementierte Ausgabeverarbeitung für HEAD
Danach denke ich, dass es so sein kann, als würde man Protokolle auf der Hauptverarbeitungsseite verwenden.
scene_exporter_v4.py
def scene_export(option):
"""Ausgabemodelle und Animationen in der Szene"""
#Vorverarbeitung
exporter = BaseExporterFactory().create(option)
exporter.export()
#Gibt an, ob das Protokoll verarbeitet werden soll
#Nachbearbeitung
Unabhängig davon, ob die Erkennung und die Beispiele angemessen sind, ist es etwas überzeugend, den Code nach der Musteranpassung zu betrachten. Wenn es nur die Menge an Code ist, ist der Basiscode der kleinste, aber da er später geändert wird, habe ich ein Muster verwendet Es ist effektiv, Zeit mit Refactoring zu verbringen.
Mit dem diesmal verwendeten Muster fällt es mir schwer, das Muster der Factory-Methode zu verstehen. Es fühlt sich an wie eine Ableitung des Factory-Musters aus dem Namen, aber ich habe erkannt, dass es sich um eine Ableitung der Vorlagenmethode handelt. Weil ich das dachte, brachte der Fluss der Musteranpassung auch zuerst die Vorlagenmethode.
Ich möchte weiter studieren und auf Ratschläge und Ratschläge aus verschiedenen Bereichen warten.
Recommended Posts