Menu
CoddyTech

Factory-Muster

Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 47 von 65.

Das Factory-Muster verlagert die Entscheidung, welche Klasse erstellt werden soll, an eine zentrale Stelle. Der Rest des Programms fragt die Factory nach „einem Goblin“ und erhält ein Objekt zurück, ohne die Klasse Goblin zu benennen.

Die Produkte haben eine gemeinsame Elternklasse, daher funktioniert der Code, der sie verwendet, mit jedem von ihnen:

# enemy.gd
class_name Enemy
extends RefCounted

var hp := 10

func attack() -> String:
	return "The enemy waits"
# goblin.gd
class_name Goblin
extends Enemy

func attack() -> String:
	return "The goblin stabs"
# orc.gd
class_name Orc
extends Enemy

func attack() -> String:
	return "The orc smashes"

Die Fabrik ist eine Klasse mit einer static func, die einen Namen in ein Objekt umwandelt. Ihr Rückgabetyp ist die übergeordnete Klasse, sodass sie jede Art von Gegner zurückgeben kann oder null für einen Namen, den sie nicht kennt:

# enemy_factory.gd
class_name EnemyFactory
extends RefCounted

static func create(kind: String) -> Enemy:
	match kind:
		"goblin":
			return Goblin.new()
		"orc":
			return Orc.new()
	return null
# main.gd
for kind in ["orc", "goblin", "slime"]:
	var enemy := EnemyFactory.create(kind)
	if enemy == null:
		print("Unknown enemy: ", kind)
	else:
		print(enemy.attack())
The orc smashes
The goblin stabs
Unknown enemy: slime

Namen wie diese stammen üblicherweise aus Daten: einer Spawn-Tabelle, einer Leveldatei oder einem Befehl, den der Spieler eingegeben hat. Die Factory ist der einzige Ort, der sie Klassen zuordnet. Um einen Dragon hinzuzufügen, braucht es also nur eine neue Datei und einen neuen Zweig in match.

Eine Factory kann das Objekt auch vorbereiten, bevor sie es zurückgibt, sodass jeder Aufrufer einen einsatzbereiten Gegner erhält:

static func create_boss(kind: String, level: int) -> Enemy:
	var boss := create(kind)
	if boss != null:
		boss.hp = 100 * level
	return boss

EnemyFactory.create_boss("orc", 3) gibt einen Orc mit 300 HP zurück.

challenge icon

Aufgabe

Mittel

Eine Spawn-Tabelle nennt Gegner und Level. Enemy (enemy.gd) und seine Unterklasse Goblin (goblin.gd) sind bereits geschrieben; vervollständige den Rest:

  • In orc.gd übergibt der Konstruktor _init(level) den Namen Orc, 25 * level HP und 4 + level Schaden an den Elternkonstruktor, so wie es Goblin macht.
  • In enemy_factory.gd gibt static func create(kind, level) einen Goblin für goblin und einen Orc für orc zurück, jeweils mit diesem Level erstellt. Groß- und Kleinschreibung im Namen spielt keine Rolle (ORC ist ein Orc). Jeder andere Name gibt null zurück.

Der bereitgestellte Code liest ein, wie viele Spawns folgen, dann eine Zeile mit KIND LEVEL pro Spawn, und gibt jeden Gegner oder Unknown enemy: KIND aus, gefolgt von der Anzahl der gespawnten Gegner. Für goblin 2, Orc 3 und slime 1 lautet die Ausgabe:

Goblin: 20 HP, 4 damage
Orc: 75 HP, 7 damage
Unknown enemy: slime
Spawned: 2

Dein Code gehört in enemy_factory.gd und orc.gd. main.gd enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.

Probier es selbst

extends Node

func _ready():
	# Vorgegebener Eingabe-/Ausgabecode: Lass ihn unverändert
	var spawned := 0
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		var enemy := EnemyFactory.create(parts[0], int(parts[1]))
		if enemy == null:
			print("Unknown enemy: ", parts[0])
		else:
			spawned += 1
			print(enemy.describe())
	print("Spawned: ", spawned)
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-GDScript-Compiler