Паттерн «Фабрика»
Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 47 из 65.
Паттерн Factory переносит выбор класса для создания в одно место. Остальная часть программы просит фабрику создать «гоблина» и получает объект, не называя класс Goblin.
У продуктов есть общий родительский класс, поэтому код, который их использует, работает с любым из них:
# 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"Фабрика — это класс со static func, который превращает имя в объект. Его тип возвращаемого значения — родительский класс, поэтому он может возвращать врага любого типа или null, если ему неизвестно такое имя:
# 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: slimeТакие имена обычно берутся из данных: таблицы появления, файла уровня или команды, введённой игроком. Фабрика — единственное место, где они сопоставляются с классами, поэтому добавление Dragon требует одного нового файла и одной новой ветви в match.
Фабрика также может настроить объект перед его возвратом, чтобы каждый вызывающий код получал готового к использованию врага:
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) возвращает Orc с 300 HP.
Задание
СреднеТаблица появления задаёт врагов и уровни. Класс Enemy (enemy.gd) и его подкласс Goblin (goblin.gd) уже написаны; закончи остальное:
- В
orc.gdконструктор_init(level)передаёт родительскому конструктору имяOrc,25 * levelHP и4 + levelурона, как это делаетGoblin. - В
enemy_factory.gdфункцияstatic func create(kind, level)возвращаетGoblinдляgoblinиOrcдляorc, созданных с этим уровнем. Регистр букв в имени не имеет значения (ORC— это орк). Для любого другого имени возвращаетсяnull.
Предоставленный код считывает количество следующих появлений, затем по одной строке KIND LEVEL для каждого появления и выводит каждого врага либо Unknown enemy: KIND, а затем количество появившихся врагов. Для goblin 2, Orc 3 и slime 1 вывод будет таким:
Goblin: 20 HP, 4 damage
Orc: 75 HP, 7 damage
Unknown enemy: slime
Spawned: 2Твой код нужно добавить в enemy_factory.gd и orc.gd. В main.gd находится предоставленный код ввода/вывода, его нельзя редактировать.
Попробуйте сами
extends Node
func _ready():
# Предоставленный код ввода/вывода: оставьте его без изменений
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)
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово selfМетодыСвойстваКонструктор (_init)Повторение: простой калькулятор4Полиморфизм
Переопределение методов: повторениеУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовПовторение — калькулятор фигур7Сигналы
Что такое сигнал?Объявление и отправкаПодключение к сигналамСигналы с аргументамиПовторение — система здоровья10Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»2Свойства классов
Переменные экземпляра и классаСтатические функцииСеттеры свойствГеттеры свойствПриватность по соглашениюПовторение — менеджер банковского счёта5Инкапсуляция
Открытые и закрытые членыПроверка данных с помощью сеттеровСокрытие информацииСвойства только для чтенияПовторение — система учета студентов8Продвинутые концепции ООП
Композиция и наследованиеВнутренние классыУзлы как компонентыRefCounted и NodeПеречисления в классах11Проект: Управление библиотекой
Обзор проектаКлассы книг и пользователей3Наследование
Основы наследованияКлючевое слово superПереопределение методовЦепочки наследованияПроверка типов с помощью isПовторение — иерархия сотрудников6Специальные методы
Введение в виртуальные методыМетод _to_stringПользовательские итераторыПовторение: пользовательский список9Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн «Одиночка»Паттерн «Фабрика»Паттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор GDScript