模板方法模式
本课属于 Coddy GDScript 学习旅程的“面向对象编程”单元。第 53 课,共 65 课。
模板方法模式会在父类中固定算法各步骤的顺序,并让每个子类补充其中一些步骤。负责运行这些步骤的父类方法就是模板方法。
# 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() -> voidplay() 是模板:每个关卡都会按此顺序加载、生成敌人并完成。不同的步骤是抽象的,因此每个子类都必须编写这些步骤:
# forest_level.gd
class_name ForestLevel
extends Level
func get_level_name() -> String:
return "Forest"
func spawn_enemies() -> void:
print("3 wolves appear")CaveLevel 的写法相同,名称是 "Cave",并且会出现 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!父类中的步骤也可以有默认实现,子类可以重写它。这样的可选步骤称为钩子:
# 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只有重写 has_boss() 并让它返回 true 的关卡才会显示首领台词。子类编写步骤,父类决定这些步骤何时运行,所以子类不改动 play(),每个关卡都遵循相同的顺序。
挑战
中等游戏会按相同的步骤以两种格式导出分数。每一行都是一个包含 "name" 和 "score" 的字典。
- 在
exporter.gd中,编写模板方法export_rows(rows):它会打印header(),然后为每一行打印format_row(row),最后打印footer(rows)。如果页眉或页脚是空字符串,就不打印。钩子header()和footer()默认返回"",而format_row()是抽象的。 CsvExporter:页眉是name,score,一行的内容是Ada,12。没有页脚。ListExporter:没有页眉,一行的内容是* Ada scored 12,页脚是带有行数的Players: N。
提供的代码会读取格式(csv 或 list)、后续行数,然后逐行读取 NAME SCORE。当格式为 list,且输入为 Ada 12 和 Bo 7 时,输出如下:
* Ada scored 12
* Bo scored 7
Players: 2你的代码应写在 exporter.gd、csv_exporter.gd 和 list_exporter.gd 中。main.gd 包含提供的输入/输出代码,不能编辑。
亲手试试
extends Node
func _ready():
# 已提供的输入和输出代码:保持原样。
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)
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: GDScript 在线编译器