Menu
CoddyTech

Pattern Template Method

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

Il pattern Template Method fissa l'ordine dei passaggi di un algoritmo in una classe genitore e permette a ogni sottoclasse di completarne alcuni. Il metodo genitore che esegue i passaggi è il template method.

# 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() è il modello: ogni livello viene caricato, fa apparire i suoi nemici e viene completato, in quest'ordine. I passaggi che differiscono sono astratti, quindi ogni sottoclasse deve scriverli:

# forest_level.gd
class_name ForestLevel
extends Level

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

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

CaveLevel è scritto allo stesso modo, con il 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!

Un passaggio può anche avere un valore predefinito nella classe genitore che una sottoclasse può sovrascrivere. Un passaggio opzionale di questo tipo si chiama hook:

# 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

Solo un livello che sovrascrive has_boss() per restituire true ottiene la riga del boss. Le sottoclassi definiscono i passaggi e la classe genitore decide quando vengono eseguiti, quindi una sottoclasse lascia invariato play() e ogni livello segue lo stesso ordine.

challenge icon

Sfida

Medio

Un gioco esporta i propri punteggi in due formati seguendo gli stessi passaggi. Le righe sono Dictionary con un "name" e un "score".

  • In exporter.gd, scrivi il metodo template export_rows(rows): stampa header(), poi format_row(row) per ogni riga e infine footer(rows). Un’intestazione o un piè di pagina che è una stringa vuota non viene stampato. Gli hook header() e footer() restituiscono "" per impostazione predefinita, mentre format_row() è astratto.
  • CsvExporter: l’intestazione è name,score e una riga è Ada,12. Nessun piè di pagina.
  • ListExporter: nessuna intestazione, una riga è * Ada scored 12 e il piè di pagina è Players: N, dove N è il numero di righe.

Il codice fornito legge il formato (csv o list), il numero di righe successive e poi una riga NAME SCORE per linea. Per list con Ada 12 e Bo 7, l’output è:

* Ada scored 12
* Bo scored 7
Players: 2

Il tuo codice va inserito in exporter.gd, csv_exporter.gd e list_exporter.gd. main.gd contiene il codice di input/output fornito e non può essere modificato.

Provalo tu

extends Node

func _ready():
	# Supplied input/output code: keep it as it is
	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 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