Patrón Factory
Parte de la sección Programación orientada a objetos del Journey de GDScript de Coddy. Lección 47 de 65.
El patrón Factory centraliza la elección de qué clase crear. El resto del programa le pide a la fábrica «un goblin» y recibe un objeto, sin nombrar la clase Goblin.
Los productos comparten una clase padre, así que el código que los usa funciona con cualquiera de ellos:
# 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 fábrica es una clase con una static func que convierte un nombre en un objeto. Su tipo de retorno es la clase padre, por lo que puede devolver cualquier tipo de enemigo, o null para un nombre que no reconoce:
# 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: slimeNombres como estos suelen provenir de datos: una tabla de aparición, un archivo de nivel, un comando que escribió el jugador. La fábrica es el único lugar que los asigna a clases, así que añadir un Dragon requiere un archivo nuevo y una rama nueva en match.
Una fábrica también puede preparar el objeto antes de devolverlo, para que cada persona que lo solicite obtenga un enemigo listo para usar:
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) devuelve un Orc con 300 HP.
Desafío
IntermedioUna tabla de aparición indica enemigos y niveles. Ya están escritos Enemy (enemy.gd) y su subclase Goblin (goblin.gd); termina el resto:
- En
orc.gd, el constructor_init(level)pasa el nombreOrc,25 * levelHP y4 + levelde daño al constructor de la clase padre, igual que haceGoblin. - En
enemy_factory.gd,static func create(kind, level)devuelve unGoblinparagobliny unOrcparaorc, creado con ese nivel. No importa que las letras del nombre estén en mayúsculas (ORCes un orco). Cualquier otro nombre devuelvenull.
El código proporcionado lee cuántas apariciones siguen y, después, una línea KIND LEVEL por aparición, e imprime cada enemigo o Unknown enemy: KIND y, después, cuántos enemigos aparecieron. Para goblin 2, Orc 3 y slime 1, la salida es:
Goblin: 20 HP, 4 damage
Orc: 75 HP, 7 damage
Unknown enemy: slime
Spawned: 2Tu código va en enemy_factory.gd y orc.gd. main.gd contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
extends Node
func _ready():
# Código de entrada/salida proporcionado: déjalo tal como está
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)
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Fundamentos de la programación orientada a objetos
Archivos externosIntroducción a la programación orientada a objetosClases vs. objetosLa palabra clave selfMétodosPropiedadesConstructor (_init)Repaso: calculadora sencilla4Polimorfismo
Repaso de la sobrescritura de métodosTipado patoClases y métodos abstractosDiseño de interfacesRepaso: calculadora de formas7Señales
¿Qué es una señal?Declarar y emitirConectarse a las señalesSeñales con argumentosRepaso: sistema de salud10Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite2Propiedades de clase
Variables de instancia y estáticasFunciones estáticasMétodos setter de propiedadesMétodos getter de propiedadesPrivado por convenciónRepaso: administrador de cuentas bancarias5Encapsulación
Miembros públicos y privadosValidación con settersOcultación de informaciónPropiedades de solo lecturaRepaso: sistema de registros de estudiantes8Conceptos avanzados de POO
Composición frente a herenciaClases internasNodos como componentesRefCounted frente a NodeEnums en clases3Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosCadenas de herenciaComprobaciones de tipo con isRepaso: jerarquía de empleados6Métodos especiales
Introducción a los métodos virtualesEl método _to_stringIteradores personalizadosRepaso: lista personalizada9Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de GDScript online