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: slimeNomi 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 bossEnemyFactory.create_boss("orc", 3) restituisce un Orc con 300 HP.
Sfida
MedioUna 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 nomeOrc, 25 * level HP e 4 + level danni al costruttore della classe genitore, come faGoblin. - In
enemy_factory.gd,static func create(kind, level)restituisce unGoblinpergobline unOrcperorc, creati con quel livello. Le lettere maiuscole nel nome non contano (ORCè un orc). Qualsiasi altro nome restituiscenull.
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: 2Il 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)
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
1Fondamenti della programmazione orientata agli oggetti
File esterniIntroduzione alla programmazione orientata agli oggettiClassi e oggetti a confrontoLa parola chiave selfMetodiProprietàCostruttore (_init)Riepilogo - Calcolatrice semplice4Polimorfismo
Ripasso dell'override dei metodiDuck typingClassi e metodi astrattiProgettazione delle interfacceRiepilogo - Calcolatore di forme7Segnali
Che cos'è un segnale?Dichiarare ed emettereCollegarsi ai segnaliSegnali con argomentiRipasso - Sistema della salute10Pattern di progettazione, parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern Composite2Proprietà delle classi
Variabili di istanza e staticheFunzioni staticheSetter delle proprietàGetter delle proprietàPrivato per convenzioneRiepilogo - Gestore di conti bancari5Incapsulamento
Membri pubblici e privatiValidazione con i setterNascondimento delle informazioniProprietà di sola letturaRiepilogo - Sistema di gestione dei dati degli studenti8Concetti avanzati di OOP
Composizione vs ereditarietàClassi interneNodi come componentiRefCounted vs NodeEnum nelle classi11Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente3Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiCatene di ereditarietàControlli di tipo con isRipasso - Gerarchia dei dipendenti6Metodi speciali
Introduzione ai metodi virtualiIl metodo _to_stringIteratori personalizzatiRiepilogo - Lista personalizzata9Modelli di progettazione, parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern ObserverPattern StrategyEsercitati da solo: Compilatore GDScript online