ZEN_OF_PYTHON Telegram 4546
Фабрики в Python

В программировании довольно часто встречается задача: в зависимости от входных данных нужно выбрать подходящий класс для обработки. Например, у нас есть XML-файлы и JSON-файлы, и мы хотим написать систему, которая будет их импортировать.

На первый взгляд решение простое — внутри метода проверять расширение файла и создавать соответствующий объект. Но у такого подхода есть несколько серьёзных недостатков. Именно здесь на помощь приходит паттерн «Фабрика».

Рассмотрим упрощённый пример кода:


class XMLImporter:
def __init__(self, filename):
self.filename = filename

def execute(self):
print("XML imported from", self.filename)


class JSONImporter:
def __init__(self, filename):
self.filename = filename

def execute(self):
print("JSON imported from", self.filename)


class Document:
def import_file(self, filename):
if filename.endswith(".xml"):
importer = XMLImporter(filename)
elif filename.endswith(".json"):
importer = JSONImporter(filename)
data = importer.execute()


document = Document()
document.import_file("text.xml")
document.import_file("text.json")


На первый взгляд код рабочий, но здесь нарушаются два принципа SOLID:

1️⃣ Принцип единственной ответственности (Single Responsibility Principle): класс Document отвечает сразу за создание объектов XMLImporter, JSONImporter и их использование.

2️⃣ Принцип открытости / закрытости (Open / Closed Principle).
Если появится новый формат (например, CSV), придётся снова лезть в метод import_file и расширять блок if / elif.


Решение: фабрика

Чтобы убрать ответственность за создание объектов из класса Document, вводится так называемася фабрика. Это объект, который берёт на себя ответственность за создание других объектов. Она не избавляет нас полностью от изменения кода при добавлении новых форматов, но значительно улучшает читаемость, гибкость и расширяемость системы.


class ImporterFactory:
def get_importer(self, filename):
if filename.endswith(".xml"):
return XMLImporter(filename)
elif filename.endswith(".json"):
return JSONImporter(filename)


Теперь Document больше не знает, как именно создаются нужные классы. Ему просто передают готовую фабрику:


class Document:
def __init__(self, factory):
self.factory = factory

def import_file(self, filename):
importer = self.factory.get_importer(filename)
data = importer.execute()


factory = ImporterFactory()
document = Document(factory)

document.import_file("text.xml")
document.import_file("text.json")


Преимущества фабрики

1️⃣ Изоляция ответственности: логика создания объектов теперь сосредоточена только в одном месте — в ImporterFactory.
2️⃣ Гибкость: если нужно добавить поддержку нового формата (CSV, YAML и т.д.), достаточно изменить фабрику, не трогая Document.
3️⃣ Удобное тестирование: в тестах можно подменить фабрику на «фиктивную» (mock) и проверять работу Document независимо от импортеров.


Что дальше?

Фабрика — это базовый паттерн. На его основе строятся более сложные подходы, например:

🔘 Factory Method — когда создание объектов делегируется подклассам.
🔘 Abstract Factory — когда фабрика создаёт целые семейства объектов, согласованных между собой.

#основы
@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
👎4🔥21



tgoop.com/zen_of_python/4546
Create:
Last Update:

Фабрики в Python

В программировании довольно часто встречается задача: в зависимости от входных данных нужно выбрать подходящий класс для обработки. Например, у нас есть XML-файлы и JSON-файлы, и мы хотим написать систему, которая будет их импортировать.

На первый взгляд решение простое — внутри метода проверять расширение файла и создавать соответствующий объект. Но у такого подхода есть несколько серьёзных недостатков. Именно здесь на помощь приходит паттерн «Фабрика».

Рассмотрим упрощённый пример кода:


class XMLImporter:
def __init__(self, filename):
self.filename = filename

def execute(self):
print("XML imported from", self.filename)


class JSONImporter:
def __init__(self, filename):
self.filename = filename

def execute(self):
print("JSON imported from", self.filename)


class Document:
def import_file(self, filename):
if filename.endswith(".xml"):
importer = XMLImporter(filename)
elif filename.endswith(".json"):
importer = JSONImporter(filename)
data = importer.execute()


document = Document()
document.import_file("text.xml")
document.import_file("text.json")


На первый взгляд код рабочий, но здесь нарушаются два принципа SOLID:

1️⃣ Принцип единственной ответственности (Single Responsibility Principle): класс Document отвечает сразу за создание объектов XMLImporter, JSONImporter и их использование.

2️⃣ Принцип открытости / закрытости (Open / Closed Principle).
Если появится новый формат (например, CSV), придётся снова лезть в метод import_file и расширять блок if / elif.


Решение: фабрика

Чтобы убрать ответственность за создание объектов из класса Document, вводится так называемася фабрика. Это объект, который берёт на себя ответственность за создание других объектов. Она не избавляет нас полностью от изменения кода при добавлении новых форматов, но значительно улучшает читаемость, гибкость и расширяемость системы.


class ImporterFactory:
def get_importer(self, filename):
if filename.endswith(".xml"):
return XMLImporter(filename)
elif filename.endswith(".json"):
return JSONImporter(filename)


Теперь Document больше не знает, как именно создаются нужные классы. Ему просто передают готовую фабрику:


class Document:
def __init__(self, factory):
self.factory = factory

def import_file(self, filename):
importer = self.factory.get_importer(filename)
data = importer.execute()


factory = ImporterFactory()
document = Document(factory)

document.import_file("text.xml")
document.import_file("text.json")


Преимущества фабрики

1️⃣ Изоляция ответственности: логика создания объектов теперь сосредоточена только в одном месте — в ImporterFactory.
2️⃣ Гибкость: если нужно добавить поддержку нового формата (CSV, YAML и т.д.), достаточно изменить фабрику, не трогая Document.
3️⃣ Удобное тестирование: в тестах можно подменить фабрику на «фиктивную» (mock) и проверять работу Document независимо от импортеров.


Что дальше?

Фабрика — это базовый паттерн. На его основе строятся более сложные подходы, например:

🔘 Factory Method — когда создание объектов делегируется подклассам.
🔘 Abstract Factory — когда фабрика создаёт целые семейства объектов, согласованных между собой.

#основы
@zen_of_python

BY Zen of Python


Share with your friend now:
tgoop.com/zen_of_python/4546

View MORE
Open in Telegram


Telegram News

Date: |

In the “Bear Market Screaming Therapy Group” on Telegram, members are only allowed to post voice notes of themselves screaming. Anything else will result in an instant ban from the group, which currently has about 75 members. Earlier, crypto enthusiasts had created a self-described “meme app” dubbed “gm” app wherein users would greet each other with “gm” or “good morning” messages. However, in September 2021, the gm app was down after a hacker reportedly gained access to the user data. Telegram Channels requirements & features The administrator of a telegram group, "Suck Channel," was sentenced to six years and six months in prison for seven counts of incitement yesterday. How to Create a Private or Public Channel on Telegram?
from us


Telegram Zen of Python
FROM American