Что значит паттерн Factory?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое паттерн Factory (Фабрика)?
Паттерн Factory — это порождающий шаблон проектирования (creational design pattern), который предоставляет интерфейс для создания объектов в суперклассе, позволяя подклассам изменять тип создаваемых объектов. Основная цель — инкапсуляция логики создания объектов, отделив код, который создаёт объекты, от кода, который их использует. Это делает систему более гибкой, расширяемой и соответствующей принципу инверсии зависимостей (Dependency Inversion Principle).
Ключевые идеи и варианты паттерна
Паттерн Factory существует в нескольких основных формах:
- Простая фабрика (Simple Factory) — не является полноценным паттерном из каталога GoF, но широко используется. Это класс с методом, который на основе входного параметра возвращает один из нескольких возможных объектов.
- Фабричный метод (Factory Method) — определяет интерфейс для создания объекта, но оставляет подклассам решение о том, экземпляр какого класса создавать. Позволяет делегировать инстанцирование подклассам.
- Абстрактная фабрика (Abstract Factory) — предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов.
Зачем он нужен в автоматизации тестирования?
В контексте QA Automation паттерн Factory — это мощный инструмент для управления сложностью и повышения поддерживаемости тестового фреймворка. Вот его основные преимущества:
- Управление созданием сложных объектов: Веб-драйверы (Selenium WebDriver), страницы (Page Objects), клиенты API, конфигурации тестовых данных часто требуют нетривиальной настройки. Фабрика централизует эту логику.
- Поддержка мульти-браузерности и мульти-платформенности: Легко создавать драйвер для Chrome, Firefox или мобильного эмулятора на основе конфигурации.
- Изоляция тестов от деталей создания: Тест не должен знать, как именно инициализируется
WebDriverили откуда берутся тестовые данные (JSON, база данных, API). Он просто запрашивает нужный объект у фабрики. - Упрощение поддержки и рефакторинга: Если способ создания объекта меняется (например, добавляются новые опции), правки вносятся в одном месте — в классе-фабрике, а не в сотнях тестов.
- Внедрение зависимостей (Dependency Injection): Фабрики часто используются вместе с DI-контейнерами для предоставления готовых, сконфигурированных зависимостей.
Пример: Фабрика для создания WebDriver
Рассмотрим практический пример Simple Factory для создания экземпляра Selenium WebDriver.
// Интерфейс или абстрактный класс, определяющий фабричный метод.
public interface WebDriverFactory {
WebDriver createDriver();
}
// Конкретные фабрики, реализующие логику создания.
public class ChromeDriverFactory implements WebDriverFactory {
@Override
public WebDriver createDriver() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless"); // Пример настройки
options.addArguments("--disable-gpu");
return new ChromeDriver(options);
}
}
public class FirefoxDriverFactory implements WebDriverFactory {
@Override
public WebDriver createDriver() {
FirefoxOptions options = new FirefoxOptions();
options.addArguments("-headless");
return new FirefoxDriver(options);
}
}
// Класс, который использует фабрику (например, базовый класс для тестов).
public class TestBase {
protected WebDriver driver;
@BeforeEach
public void setUp() {
// Тип фабрики можно определять из конфигурационного файла, переменной окружения и т.д.
String browser = System.getProperty("browser", "chrome");
WebDriverFactory factory;
switch (browser.toLowerCase()) {
case "firefox":
factory = new FirefoxDriverFactory();
break;
case "chrome":
default:
factory = new ChromeDriverFactory();
}
driver = factory.createDriver();
driver.manage().window().maximize();
}
}
Пример: Фабрика для создания Page Objects
Фабрика может упростить создание Page Objects, особенно если их конструкторы становятся сложными.
# page_factory.py
from pages.login_page import LoginPage
from pages.dashboard_page import DashboardPage
from selenium.webdriver.remote.webdriver import WebDriver
class PageFactory:
def __init__(self, driver: WebDriver):
self._driver = driver
def create_login_page(self) -> LoginPage:
# Здесь может быть дополнительная логика инициализации страницы
return LoginPage(self._driver)
def create_dashboard_page(self) -> DashboardPage:
return DashboardPage(self._driver)
# В тесте
def test_successful_login(driver): # driver получен из фикстуры
page_factory = PageFactory(driver)
login_page = page_factory.create_login_page()
login_page.open()
login_page.login("user", "pass")
dashboard_page = page_factory.create_dashboard_page()
assert dashboard_page.is_user_menu_displayed()
Заключение
Использование паттерна Factory в автоматизации тестирования — это признак зрелого, хорошо спроектированного фреймворка. Он напрямую способствует соблюдению принципов DRY (Don't Repeat Yourself) и Single Responsibility, так как логика создания объектов выносится в отдельные классы. Это значительно снижает связанность кода, делает тесты более чистыми и устойчивыми к изменениям в инфраструктуре. Внедрение фабрик — это инвестиция в долгосрочную поддерживаемость и масштабируемость вашего автотестового комплекса.