Einführung in Entwurfsmuster
Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 45 von 65.
Ein Entwurfsmuster ist eine bekannte, benannte Art, Klassen für ein Problem anzuordnen, das in Programm nach Programm wiederkehrt. Es ist weder eine Bibliothek noch Code zum Kopieren: Es beschreibt, welche Objekte es gibt, wofür jedes einzelne verantwortlich ist und wie sie zusammenarbeiten. Du schreibst den Code selbst und passt ihn an dein Spiel an.
Muster geben Entwicklern auch eine gemeinsame Sprache. „Gegner kommen aus einer Fabrik“ oder „die Gesundheitsleiste beobachtet den Spieler“ erklärt einem Teammitglied, wie der Code aufgebaut ist, noch bevor es eine Datei öffnet.
Hier ist ein Problem, das ein Muster löst. Ein Level zu starten bedeutet, mit drei Objekten zu kommunizieren, und jedes Skript, das ein Level startet, wiederholt diese Zeilen:
var music := MusicPlayer.new()
var level_map := LevelMap.new()
var hud := Hud.new()
music.play("forest.ogg")
level_map.load_map(1)
hud.show_hearts(3)Das Fassadenmuster stellt diesen Objekten eine Klasse voran und gibt ihr eine einfache Methode:
# game_facade.gd
class_name GameFacade
extends RefCounted
var music := MusicPlayer.new()
var level_map := LevelMap.new()
var hud := Hud.new()
func start_level(number: int) -> void:
music.play("forest.ogg")
level_map.load_map(number)
hud.show_hearts(3)# main.gd
var game := GameFacade.new()
game.start_level(1)Music: playing forest.ogg
Map: level 1 loaded
HUD: hearts 3Der Rest des Programms ruft start_level() auf, und wenn sich das Starten eines Levels ändert, bearbeitest du eine Datei.
Muster werden nach dem Problem gruppiert, das sie lösen:
- Erzeugungsmuster steuern, wie Objekte erstellt werden: Singleton, Factory.
- Strukturmuster kombinieren Objekte zu größeren Strukturen: Facade, Adapter, Decorator, Composite.
- Verhaltensmuster organisieren, wie Objekte zusammenarbeiten: Observer, Strategy, Command, Template Method, State.
Dieses Kapitel und das nächste behandeln diese Muster. Jedes davon baut auf dem auf, was du bereits kennst: Klassen in eigenen Dateien, Vererbung, Polymorphie, Komposition und Signale.
Aufgabe
EinfachEin Spiel startet und beendet Level mithilfe von drei bereits geschriebenen Objekten: MusicPlayer (music_player.gd), LevelMap (level_map.gd) und Hud (hud.gd). Schreibe die Fassade GameFacade, die vor diesen Objekten sitzt:
- Sie erstellt je ein
MusicPlayer-,LevelMap- undHud-Objekt in ihren Membervariablen. start_level(number, hearts)spielt den Tracklevel_N.ogg(N ist die Levelnummer) oderboss.ogg, wenn die Zahl ein Vielfaches von5ist, lädt dann die Karte dieses Levels und zeigt anschließend die Herzen an.quit_level()blendet das HUD aus und stoppt dann die Musik.
Der bereitgestellte Code liest ein, wie viele Befehle folgen, und danach einen Befehl pro Zeile: start NUMBER HEARTS oder quit. Für start 5 2 und quit lautet die Ausgabe:
Music: playing boss.ogg
Map: level 5 loaded
HUD: hearts 2
HUD: hidden
Music: stoppedDein Code gehört in game_facade.gd. main.gd enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
extends Node
func _ready():
# Vorgegebener Ein-/Ausgabecode: unverändert lassen
var game := GameFacade.new()
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "start":
game.start_level(int(parts[1]), int(parts[2]))
elif parts[0] == "quit":
game.quit_level()
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort selfMethodenEigenschaftenKonstruktor (_init)Wiederholung – Einfacher Taschenrechner4Polymorphie
Methodenüberschreibung erneut betrachtetDuck-TypisierungAbstrakte Klassen und MethodenSchnittstellendesignRückblick – Formrechner2Klassenattribute
Instanz- vs. statische VariablenStatische FunktionenProperty-SetterProperty-GetterPrivat nach KonventionWiederholung – Bankkontenverwaltung5Kapselung
Öffentliche und private MemberValidierung mit SetternInformationsverbergenSchreibgeschützte EigenschaftenRückblick – System zur Schülerverwaltung8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungInnere KlassenNodes als KomponentenRefCounted vs. NodeEnums in Klassen11Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Vererbung
Grundlegende VererbungDas Schlüsselwort superMethodenüberschreibungVererbungskettenTypprüfungen mit isWiederholung – Mitarbeiterhierarchie6Spezielle Methoden
Einführung in virtuelle MethodenDie _to_string-MethodeBenutzerdefinierte IteratorenRückblick – Benutzerdefinierte Liste9Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBeobachter-MusterStrategie-Muster12Abschließende Herausforderungen
E-Learning-PlattformBankensystemEntwicklung von SpielfigurenFahrzeugvermietungÜbe selbstständig: Online-GDScript-Compiler