Фабричные функции
Часть раздела Объектно-ориентированное программирование путешествия по Lua на Coddy. Урок 62 из 70.
На протяжении всего этого курса вы создавали объекты, напрямую вызывая конструкторы: Circle:new(), Rectangle:new() и так далее. Но что, если вы хотите создавать разные типы объектов в зависимости от некоторого условия, чтобы вызывающему коду не нужно было знать, какой именно класс использовать?
Здесь на помощь приходит Factory pattern. Factory — это просто function, которая создаёт и возвращает object. Главное преимущество в том, что caller doesn't need to know детали создания object. Она просто запрашивает у Factory то, что ей нужно.
local function createShape(shapeType)
if shapeType == "circle" then
return Circle:new(10)
elseif shapeType == "square" then
return Square:new(5)
end
end
-- Вызывающему коду не нужно знать о классах Circle или Square
local myShape = createShape("circle")
print(myShape:area())
Фабричная function принимает строковый аргумент и решает, какой class создать. Это централизует логику создания object в одном месте. Если позже вы добавите новый тип фигуры, вам нужно будет изменить только фабрику, а не каждый фрагмент кода, который создаёт фигуры.
Фабрики особенно полезны, когда создание object включает сложную настройку, когда вы хотите скрыть детали реализации или когда точный тип object зависит от условий выполнения, таких как пользовательский ввод или файлы конфигурации.
Задание
ЛегкоСоздадим Pet Factory! Вместо того чтобы создавать pets напрямую, вызывая constructor каждого class, ты создашь factory function, которая производит подходящий тип pet на основе простого строкового аргумента.
Ты организуешь свой код в четырёх файлах:
Dog.lua: Создай class Dog с constructor:new(name), который сохраняет имя pet. Добавь method:speak(), который возвращает string"{name} says: Woof!"(где {name} — имя dog).Cat.lua: Создай class Cat с такой же структурой: constructor:new(name)и method:speak(), который возвращает"{name} says: Meow!".PetFactory.lua: Именно здесь Factory pattern раскрывается во всей красе! Создай functioncreatePet(petType, name), которая принимает два аргумента: string, указывающую тип pet ("dog"или"cat"), и имя pet. function должна возвращать соответствующий object pet. Если тип —"dog", верни новый Dog; если"cat"— верни новый Cat.main.lua: Подключи свой модуль PetFactory с помощью require. Считай два inputs: тип pet и имя pet. Используй свою factory function, чтобы создать pet, затем вызови его method:speak()и выведи result.
Преимущество Factory pattern в том, что твоему основному коду не нужно напрямую подключать Dog или Cat. Он знает только о factory. Factory обрабатывает все детали того, какой class нужно создать.
Ты получишь два inputs:
- Тип Pet (либо
"dog", либо"cat") - Имя Pet (string)
Например, если inputs — dog и Buddy, output должен быть таким:
Buddy says: Woof!Если inputs — cat и Whiskers, output должен быть таким:
Whiskers says: Meow!Попробуйте сами
-- main.lua
-- Используйте PetFactory для создания питомцев
local PetFactory = require('PetFactory')
-- Читаем входные данные
local petType = io.read()
local petName = io.read()
-- TODO: Используйте PetFactory.createPet для создания питомца
-- TODO: Вызовите метод :speak() питомца и выведите результат
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Концепция 'self'
Таблицы с функциямиЯвный 'self'Синтаксис с двоеточиемТочка против двоеточияИтоги — Движущаяся точка4Проект: Цифровой банк
Настройка проектаМетод пополнения7Полиморфизм и переопределение
Переопределение методовВызов родительских методовУтиная типизацияОбщий интерфейсПроверка типаИтоги — Роли сотрудников2Паттерн прототипа класса
Концепция прототипаСвязывание через __indexКонструктор :new()Инициализация атрибутовНезависимые экземплярыИтоги — Автозавод5Перегрузка операторов в ООП
Сложение объектовВычитание объектовКонкатенация объектовСравнение объектов (<, >)Повторение — Математика кошелька8Инкапсуляция
Соглашения об именованииЗамыкания для приватностиДоступ через замыканияТаблицы только для чтенияЛогика валидацииИтоги — Защищенное хранилище11Паттерны проектирования (Lite)
Фабричные функцииТаблица SingletonПаттерн IteratorObserver (Слушатель)Итоги — Logger Factory3Состояние и поведение объектов
Переменные экземпляраГеттерыСеттерыВычисляемые свойстваФорматирование строкПроверка на равенствоПовторение — Оценка студента6Основы наследования
Настройка наследованияНаследование методовРасширение конструктораДобавление дочерних методовОбщее и уникальноеИтоги: Иерархия фигурПотренируйтесь самостоятельно: Онлайн-компилятор Lua