Padrão Factory
Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 47 de 65.
O padrão Factory concentra em um só lugar a escolha de qual classe criar. O restante do programa pede à fábrica "um goblin" e recebe um objeto, sem nomear a classe Goblin.
Os produtos compartilham uma classe pai, então o código que os utiliza funciona com qualquer um deles:
# 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"A fábrica é uma classe com uma static func que transforma um nome em um objeto. Seu tipo de retorno é a classe pai, então ela pode retornar qualquer tipo de inimigo, ou null para um nome que não conhece:
# 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: slimeNomes como esses geralmente vêm de dados: uma tabela de surgimento, um arquivo de fase, um comando digitado pelo jogador. A fábrica é o único lugar que os associa a classes, então adicionar um Dragon exige um novo arquivo e um novo ramo no match.
Uma fábrica também pode configurar o objeto antes de retorná-lo, para que cada chamador receba um inimigo pronto 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) retorna um Orc com 300 HP.
Desafio
MédioUma tabela de surgimento especifica inimigos e níveis. Enemy (enemy.gd) e sua subclasse Goblin (goblin.gd) já estão escritos; termine o restante:
- Em
orc.gd, o construtor_init(level)passa o nomeOrc,25 * levelHP e4 + levelde dano para o construtor da classe pai, comoGoblinfaz. - Em
enemy_factory.gd,static func create(kind, level)retorna umGoblinparagobline umOrcparaorc, criados com esse nível. Letras maiúsculas no nome não importam (ORCé um orc). Qualquer outro nome retornanull.
O código fornecido lê quantos surgimentos vêm a seguir, depois uma linha KIND LEVEL para cada surgimento, e exibe cada inimigo ou Unknown enemy: KIND, e então quantos inimigos surgiram. Para goblin 2, Orc 3 e slime 1, a saída é:
Goblin: 20 HP, 4 damage
Orc: 75 HP, 7 damage
Unknown enemy: slime
Spawned: 2Seu código deve ficar em enemy_factory.gd e orc.gd. main.gd contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
extends Node
func _ready():
# Código de entrada/saída fornecido: mantenha-o 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 lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Fundamentos da POO
Arquivos externosIntrodução à POOClasses vs. objetosA palavra-chave selfMétodosPropriedadesConstrutor (_init)Revisão - Calculadora simples4Polimorfismo
Revisitando a Sobrescrita de MétodosDuck TypingClasses e Métodos AbstratosDesign de InterfacesRevisão - Calculadora de Formas7Sinais
O que é um sinal?Declarando e emitindoConectando-se a sinaisSinais com argumentosRevisão - Sistema de saúde10Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite2Propriedades de Classe
Variáveis de Instância vs. EstáticasFunções EstáticasMétodos Setters de PropriedadeMétodos Getters de PropriedadePrivado por ConvençãoRecapitulando: Gerenciador de Conta Bancária5Encapsulamento
Membros públicos e privadosValidação com settersOcultação de informaçõesPropriedades somente para leituraRevisão - Sistema de registros de alunos8Conceitos Avançados de POO
Composição vs. HerançaClasses InternasNós como ComponentesRefCounted vs. NodeEnums em Classes3Herança
Herança básicaA palavra-chave superSobrescrita de métodosCadeias de herançaVerificações de tipo com isRevisão - Hierarquia de funcionários6Métodos especiais
Introdução aos métodos virtuaisO método _to_stringIteradores personalizadosRevisão - Lista personalizada9Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão StrategyPratique por conta própria: Compilador de GDScript online