"""Паттерн Фабричный Метод полезен, когда нужно создавать объекты,
но заранее неизвестно, какого типа они должны быть.
Например, нам неоходимо работать с разными типами файлов изображений.
Для каждого расширения будет создан отдельный подкласс."""
from abc import ABC, abstractmethod
# Сначала создается базовый абстрактный класс
class ImageReader(ABC):
def __init__(self, path):
self.path = path
@abstractmethod
def read(self):
"""Этот метод обязательно должен быть реализован в каждом подклассе"""
pass
def log_reading(self):
"""Этот метод будет унаследован всеми подклассами - будет общим"""
print(f"Изображение по адресу {self.path} было прочитано.")
class GifReader(ImageReader):
def read(self):
print(f"Read gif image")
class JPEGReader(ImageReader):
def read(self):
print(f"Read jpeg image")
class PNGReader(ImageReader):
def read(self):
print(f"Read png image")
# Проверим, что нужный класс создается и методы работают
png = PNGReader('image.png')
png.read()
png.log_reading()
print()
# Создаем фабрику
def extension_of_path(path):
"""Вспомогательная функция. Возвращает расширение из пути к файлу"""
position_of_last_dot = path.rfind('.')
return path[position_of_last_dot + 1:]
# Глобальная переменная, в которой каждому расширению сопоставляется соответствующий класс
READERS = {
'gif': GifReader,
'jpeg': JPEGReader,
'png': PNGReader
}
def get_image_reader(path):
reader_class = READERS[extension_of_path(path)]
return reader_class(path)
img_class = get_image_reader('image.jpeg')
img_class.read()
img_class.log_reading()