Menu
CoddyTech

Padrão Template Method

Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 53 de 65.

O padrão Template Method fixa a ordem das etapas de um algoritmo em uma classe pai e permite que cada subclasse preencha algumas das etapas. O método pai que executa as etapas é o método template.

# level.gd
@abstract
class_name Level
extends RefCounted

func play() -> void:
	print("Loading ", get_level_name())
	spawn_enemies()
	print("Level complete!")

@abstract func get_level_name() -> String
@abstract func spawn_enemies() -> void

play() é o modelo: cada nível carrega, surge com seus inimigos e é concluído, nesta ordem. As etapas que diferem são abstratas, então cada subclasse precisa escrevê-las:

# forest_level.gd
class_name ForestLevel
extends Level

func get_level_name() -> String:
	return "Forest"

func spawn_enemies() -> void:
	print("3 wolves appear")

CaveLevel é escrito da mesma forma, com o nome "Cave" e 5 bats appear.

# main.gd
var levels: Array[Level] = [ForestLevel.new(), CaveLevel.new()]
for level in levels:
	level.play()
Loading Forest
3 wolves appear
Level complete!
Loading Cave
5 bats appear
Level complete!

Uma etapa também pode ter um valor padrão na classe pai que uma subclasse pode sobrescrever. Essa etapa opcional é chamada de gancho:

# level.gd
func play() -> void:
	print("Loading ", get_level_name())
	spawn_enemies()
	if has_boss():
		print("The boss arrives")
	print("Level complete!")

func has_boss() -> bool:
	return false

Somente um nível que sobrescreve has_boss() para retornar true recebe a linha do chefe. As subclasses definem as etapas e a classe pai decide quando elas são executadas, então uma subclasse deixa play() intacto e todos os níveis seguem a mesma ordem.

challenge icon

Desafio

Médio

Um jogo exporta suas pontuações em dois formatos usando as mesmas etapas. As linhas são dicionários com um "name" e um "score".

  • Em exporter.gd, escreva o método template export_rows(rows): ele imprime header(), depois format_row(row) para cada linha e, em seguida, footer(rows). Um cabeçalho ou rodapé que seja uma string vazia não é impresso. Por padrão, os hooks header() e footer() retornam "", e format_row() é abstrato.
  • CsvExporter: o cabeçalho é name,score, e uma linha é Ada,12. Sem rodapé.
  • ListExporter: sem cabeçalho, uma linha é * Ada scored 12, e o rodapé é Players: N com o número de linhas.

O código fornecido lê o formato (csv ou list), quantas linhas vêm a seguir e, então, uma linha NAME SCORE por linha. Para list com Ada 12 e Bo 7, a saída é:

* Ada scored 12
* Bo scored 7
Players: 2

Seu código deve ficar em exporter.gd, csv_exporter.gd e list_exporter.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 style := OS.read_string_from_stdin()
	var rows: Array = []
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		rows.append({"name": parts[0], "score": int(parts[1])})
	var exporter: Exporter = CsvExporter.new()
	if style == "list":
		exporter = ListExporter.new()
	exporter.export_rows(rows)
quiz iconTeste seus conhecimentos

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

Pratique por conta própria: Compilador de GDScript online