Autumn SALE
Фабричный метод

Фабричный метод на Python

Фабричный метод — это порождающий паттерн проектирования, который решает проблему создания различных продуктов, без указания конкретных классов продуктов.

Фабричный метод задаёт метод, который следует использовать вместо вызова оператора new для создания объектов-продуктов. Подклассы могут переопределить этот метод, чтобы изменять тип создаваемых продуктов.

Сложность:

Популярность:

Применимость: Паттерн можно часто встретить в любом Python-коде, где требуется гибкость при создании продуктов.

Признаки применения паттерна: Фабричный метод можно определить по создающим методам, которые возвращают объекты продуктов через абстрактные типы или интерфейсы. Это позволяет переопределять типы создаваемых продуктов в подклассах.

Концептуальный пример

Этот пример показывает структуру паттерна Фабричный метод, а именно — из каких классов он состоит, какие роли эти классы выполняют и как они взаимодействуют друг с другом.

main.py: Пример структуры паттерна

from __future__ import annotations from abc import ABC, abstractmethod class Creator(ABC): """ Класс Создатель объявляет фабричный метод, который должен возвращать объект класса Продукт. Подклассы Создателя обычно предоставляют реализацию этого метода. """ @abstractmethod def factory_method(self): """ Обратите внимание, что Создатель может также обеспечить реализацию фабричного метода по умолчанию. """ pass def some_operation(self) -> str: """ Также заметьте, что, несмотря на название, основная обязанность Создателя не заключается в создании продуктов. Обычно он содержит некоторую базовую бизнес-логику, которая основана на объектах Продуктов, возвращаемых фабричным методом. Подклассы могут косвенно изменять эту бизнес-логику, переопределяя фабричный метод и возвращая из него другой тип продукта. """ # Вызываем фабричный метод, чтобы получить объект-продукт. product = self.factory_method() # Далее, работаем с этим продуктом. result = f"Creator: The same creator's code has just worked with {product.operation()}" return result """ Конкретные Создатели переопределяют фабричный метод для того, чтобы изменить тип результирующего продукта. """ class ConcreteCreator1(Creator): """ Обратите внимание, что сигнатура метода по-прежнему использует тип абстрактного продукта, хотя фактически из метода возвращается конкретный продукт. Таким образом, Создатель может оставаться независимым от конкретных классов продуктов. """ def factory_method(self) -> Product: return ConcreteProduct1() class ConcreteCreator2(Creator): def factory_method(self) -> Product: return ConcreteProduct2() class Product(ABC): """ Интерфейс Продукта объявляет операции, которые должны выполнять все конкретные продукты. """ @abstractmethod def operation(self) -> str: pass """ Конкретные Продукты предоставляют различные реализации интерфейса Продукта. """ class ConcreteProduct1(Product): def operation(self) -> str: return "{Result of the ConcreteProduct1}" class ConcreteProduct2(Product): def operation(self) -> str: return "{Result of the ConcreteProduct2}" def client_code(creator: Creator) -> None: """ Клиентский код работает с экземпляром конкретного создателя, хотя и через его базовый интерфейс. Пока клиент продолжает работать с создателем через базовый интерфейс, вы можете передать ему любой подкласс создателя. """ print(f"Client: I'm not aware of the creator's class, but it still works.\n" f"{creator.some_operation()}", end="") if __name__ == "__main__": print("App: Launched with the ConcreteCreator1.") client_code(ConcreteCreator1()) print("\n") print("App: Launched with the ConcreteCreator2.") client_code(ConcreteCreator2()) 

Output.txt: Результат выполнения

App: Launched with the ConcreteCreator1. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct1} App: Launched with the ConcreteCreator2. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct2} 

Фабричный метод на других языках программирования

Фабричный метод на C# Фабричный метод на C++ Фабричный метод на Go Фабричный метод на Java Фабричный метод на PHP Фабричный метод на Ruby Фабричный метод на Rust Фабричный метод на Swift Фабричный метод на TypeScript