Menu
CoddyTech

Pattern Factory

Fa parte della sezione Programmazione orientata agli oggetti del percorso GDScript di Coddy. Lezione 47 di 65.

Il pattern Factory sposta in un unico punto la scelta della classe da creare. Il resto del programma chiede alla factory «un goblin» e riceve in cambio un oggetto, senza nominare la classe Goblin.

I prodotti condividono una classe genitore, quindi il codice che li usa funziona con ognuno di essi:

# 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"

La factory è una classe con una static func che trasforma un nome in un oggetto. Il suo tipo restituito è la classe genitore, quindi può restituire qualsiasi tipo di nemico, oppure null per un nome che non conosce:

# 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

Nomi come questi di solito provengono dai dati: una tabella di generazione, un file di livello, un comando digitato dal giocatore. La factory è l'unico posto che li associa alle classi, quindi aggiungere un Dragon richiede un nuovo file e un nuovo ramo nel match.

Una factory può anche configurare l'oggetto prima di restituirlo, così ogni chiamante ottiene un nemico pronto all'uso:

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) restituisce un Orc con 300 HP.

challenge icon

Sfida

Medio

Una tabella di generazione indica nemici e livelli. Enemy (enemy.gd) e la sua sottoclasse Goblin (goblin.gd) sono già scritti; completa il resto:

  • In orc.gd, il costruttore _init(level) passa il nome Orc, 25 * level HP e 4 + level danni al costruttore della classe genitore, come fa Goblin.
  • In enemy_factory.gd, static func create(kind, level) restituisce un Goblin per goblin e un Orc per orc, creati con quel livello. Le lettere maiuscole nel nome non contano (ORC è un orc). Qualsiasi altro nome restituisce null.

Il codice fornito legge quanti nemici devono essere generati, poi una riga KIND LEVEL per ogni nemico e stampa ciascun nemico oppure Unknown enemy: KIND, quindi il numero di nemici generati. Per goblin 2, Orc 3 e slime 1, l'output è:

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

Il tuo codice va in enemy_factory.gd e orc.gd. main.gd contiene il codice di input/output fornito e non può essere modificato.

Provalo tu

extends Node

func _ready():
	# Codice di input/output fornito: lascialo così com'è
	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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore GDScript online