Шаблон проектирования заводского метода в Python
Вступление
В этой статье мы погрузимся в шаблон проектирования фабричного метода, реализованный в Python.
Шаблоны проектирования определяют проверенные решения различных повторяющихся проблем в разработке программного обеспечения. Они представляют собой не фактический код, а скорее способы, с помощью которых мы можем организовать наш код для достижения оптимальных результатов.
В мире ограниченных ресурсов шаблоны проектирования помогают нам достичь наибольших результатов при наименьшем количестве используемых ресурсов. Важно также отметить, что шаблоны проектирования применимы не ко всем ситуациям, и крайне важно оценить существующую проблему, чтобы выбрать наилучший подход для данного конкретного сценария.
Паттерны проектирования делятся на несколько широких категорий, хотя в основном на Творческие Паттерны, Структурные Паттерны и Поведенческие Паттерны.
Шаблон Заводского метода-это Шаблон Творческого проектирования .
Шаблон Проектирования Заводского Метода
Определение
Фабричный метод используется в объектно-ориентированном программировании как средство обеспечения фабричных интерфейсов для создания объектов. Эти интерфейсы определяют общую структуру, но не инициализируют объекты. Инициализация остается за более конкретными подклассами.
Родительский класс/интерфейс содержит все стандартное и универсальное поведение, которое может быть разделено между подклассами различных типов. Подкласс, в свою очередь, отвечает за определение и создание экземпляра объекта на основе суперкласса.
Мотивация
Основная мотивация, лежащая в основе шаблона проектирования фабричного метода, заключается в усилении слабой связи в коде путем создания абстрактного класса, который будет использоваться для создания различных типов объектов, имеющих некоторые общие атрибуты и функциональные возможности.
Это приводит к повышению гибкости и повторному использованию кода, поскольку общая функциональность не будет переписана, будучи унаследованной от одного и того же класса. Этот шаблон проектирования также известен как Виртуальный конструктор .
Шаблон проектирования фабричного метода обычно используется в библиотеках, позволяя клиентам выбирать, какой подкласс или тип объекта создавать с помощью абстрактного класса.
Фабричный метод получит информацию о требуемом объекте, создаст его экземпляр и вернет объект указанного типа. Это дает нашему приложению или библиотеке единую точку взаимодействия с другими программами или фрагментами кода, тем самым инкапсулируя нашу функциональность создания объектов.
Реализация Заводского метода
Наша программа будет представлять собой библиотеку, используемую для обработки острых объектов с точки зрения создания и других операций, таких как добавление цвета и вычисление площади формы.
Пользователи должны иметь возможность использовать нашу библиотеку для создания новых объектов. Мы можем начать с создания отдельных отдельных фигур и использования их как есть, но это будет означать, что много общей логики придется переписать для каждой доступной нам формы.
Первым шагом к решению этой проблемы было бы создание родительского класса shape , имеющего такие методы, как calculate_area()
и calculate_perimeter ()
, а также такие свойства, как размеры.
Конкретные объекты shape затем наследуются от нашего базового класса. Чтобы создать фигуру, нам нужно будет определить, какая форма требуется, и создать для нее подкласс.
Мы начнем с создания абстрактного класса для представления общей формы:
import abc class Shape(metaclass=abc.ABCMeta): @abc.abstractmethod def calculate_area(self): pass @abc.abstractmethod def calculate_perimeter(self): pass
Это базовый класс для всех наших фигур. Давайте продолжим и создадим несколько конкретных, более конкретных форм:
class Rectangle(Shape): def __init__(self, height, width): self.height = height self.width = width def calculate_area(self): return self.height * self.width def calculate_perimeter(self): return 2 * (self.height + self.width) class Square(Shape): def __init__(self, width): self.width = width def calculate_area(self): return self.width ** 2 def calculate_perimeter(self): return 4 * self.width class Circle(Shape): def __init__(self, radius): self.radius = radius def calculate_area(self): return 3.14 * self.radius * self.radius def calculate_perimeter(self): return 2 * 3.14 * self.radius
До сих пор мы создали абстрактный класс и расширили его, чтобы он соответствовал различным формам, которые будут доступны в нашей библиотеке. Для того чтобы создать различные объекты формы, клиенты должны будут знать имена и детали наших форм и отдельно выполнять их создание.
Именно здесь вступает в игру Фабричный метод .
Шаблон проектирования фабричного метода поможет нам абстрагировать доступные формы от клиента, то есть клиент не должен знать все доступные формы, а скорее создавать только то, что ему нужно во время выполнения. Это также позволит нам централизовать и инкапсулировать создание объекта.
Давайте достигнем этого, создав Фабрику фигур
, которая будет использоваться для создания конкретных классов фигур на основе входных данных клиента:
class ShapeFactory: def create_shape(self, name): if name == 'circle': radius = input("Enter the radius of the circle: ") return Circle(float(radius)) elif name == 'rectangle': height = input("Enter the height of the rectangle: ") width = input("Enter the width of the rectangle: ") return Rectangle(int(height), int(width)) elif name == 'square': width = input("Enter the width of the square: ") return Square(int(width))
Это наш интерфейс для создания. Мы не вызываем конструкторов конкретных классов, мы вызываем Factory и просим его создать форму.
Наша ShapeFactory
работает, получая информацию о форме, такую как имя и необходимые размеры. Затем наш фабричный метод create_shape()
будет использоваться для создания и возврата готовых объектов нужной формы.
Клиенту не нужно ничего знать о создании объекта или его специфике. Используя объект factory, они могут создавать объекты с минимальными знаниями о том, как они работают:
def shapes_client(): shape_factory = ShapeFactory() shape_name = input("Enter the name of the shape: ") shape = shape_factory.create_shape(shape_name) print(f"The type of object created: {type(shape)}") print(f"The area of the {shape_name} is: {shape.calculate_area()}") print(f"The perimeter of the {shape_name} is: {shape.calculate_perimeter()}")
Запуск этого кода приведет к:
Enter the name of the shape: circle Enter the radius of the circle: 7 The type of object created:The area of the circle is: 153.86 The perimeter of the circle is: 43.96
Или мы могли бы построить другую форму:
Enter the name of the shape: square Enter the width of the square: 5 The type of object created:The area of the square is: 25 The perimeter of the square is: 20
Стоит отметить, что помимо того, что клиенту не нужно много знать о процессе создания – когда мы хотим создать экземпляр объекта, мы не вызываем конструктор класса. Мы просим фабрику сделать это за нас на основе информации, которую мы передаем функции create_shape ()
.
плюсы и минусы
Плюсы
Одним из главных преимуществ использования шаблона проектирования Фабричного метода является то, что наш код становится слабо связанным, поскольку большинство компонентов нашего кода не знают о других компонентах той же кодовой базы.
Это приводит к тому, что код легко понять и протестировать, а также добавить больше функциональности к конкретным компонентам, не затрагивая и не нарушая всю программу.
Шаблон проектирования фабричного метода также помогает поддерживать Принцип Единой ответственности где классы и объекты, обрабатывающие определенную функциональность, приводят к улучшению кода.
Аферы
Создание большего количества классов в конечном итоге приводит к меньшей читабельности. В сочетании с Абстрактной фабрикой (фабрикой фабрик) код скоро станет многословным, хотя и ремонтопригодным.
Вывод
В заключение следует отметить, что Шаблон проектирования Фабричного метода позволяет создавать объекты без указания точного класса, необходимого для создания конкретного объекта. Это позволяет нам отделить наш код и повышает его повторное использование.
Важно отметить, что, как и любой другой шаблон проектирования, он подходит только для конкретных ситуаций, а не для каждого сценария развития. Оценка текущей ситуации имеет решающее значение, прежде чем принять решение о внедрении Шаблона проектирования заводского метода, чтобы воспользоваться преимуществами этого шаблона.