Шаблон проектирования фабричного метода в Python

Введение В этой статье мы углубимся в шаблон проектирования фабричного метода, реализованный на Python. Шаблоны проектирования определяют проверенные временем решения различных повторяющихся проблем в разработке программного обеспечения. Они не представляют собой реальный код, а скорее способы, с помощью которых мы можем организовать наш код для достижения оптимальных результатов. В мире ограниченных ресурсов шаблоны проектирования помогают нам достичь максимальных результатов с наименьшим количеством используемых ресурсов. Также важно отметить, что шаблоны проектирования d

Вступление

В этой статье мы углубимся в шаблон проектирования фабричного метода, реализованный на Python.

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

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

Шаблоны проектирования делятся на несколько широких категорий, но в основном это шаблоны создания, структурные шаблоны и поведенческие шаблоны.

Шаблон Factory Method - это шаблон творческого проектирования .

Шаблон проектирования фабричного метода

Определение

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

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

Мотивация

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

Это приводит к повышенной гибкости и повторному использованию кода, поскольку общие функциональные возможности не будут переписаны, будучи унаследованными от того же класса. Этот шаблон проектирования также известен как виртуальный конструктор .

Шаблон проектирования Factory Method обычно используется в библиотеках, позволяя клиентам выбирать, какой подкласс или тип объекта создать с помощью абстрактного класса.

Заводской метод получит информацию о требуемом объекте, создаст его экземпляр и вернет объект указанного типа. Это дает нашему приложению или библиотеке единую точку взаимодействия с другими программами или фрагментами кода, тем самым инкапсулируя наши функции создания объектов.

Реализация фабричного метода

Наша программа будет библиотекой, используемой для обработки объектов формы с точки зрения создания и других операций, таких как добавление цвета и вычисление площади формы.

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

Первым шагом к решению этого повторения будет создание родительского класса формы, который имеет такие методы, как calculate_area() и calculate_perimeter() , а также такие свойства, как размеры.

Затем конкретные объекты формы унаследуются от нашего базового класса. Чтобы создать фигуру, нам нужно будет определить, какая форма требуется, и создать для нее подкласс.

Мы начнем с создания абстрактного класса для представления общей формы:

 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 

Пока что мы создали абстрактный класс и расширили его, чтобы он соответствовал различным формам, которые будут доступны в нашей библиотеке. Чтобы создавать различные объекты-формы, клиенты должны знать имена и детали наших фигур и отдельно выполнять создание.

Здесь в игру вступает заводской метод.

Шаблон проектирования Factory Method поможет нам абстрагироваться от доступных форм от клиента, то есть клиенту не нужно знать все доступные формы, а только создавать то, что им нужно, во время выполнения. Это также позволит нам централизовать и инкапсулировать создание объекта.

Давайте добьемся этого, создав ShapeFactory который будет использоваться для создания определенных классов фигур на основе ввода клиента:

 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() будет использоваться для создания и возврата готовых объектов желаемой формы.

Заказчику не нужно ничего знать о создании объекта или его особенностях. Используя объект фабрики, они могут создавать объекты с минимальными знаниями о том, как они работают:

 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: <class '__main__.Circle'> 
 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: <class '__main__.Square'> 
 The area of the square is: 25 
 The perimeter of the square is: 20 

Стоит отметить, что помимо того, что клиенту не нужно много знать о процессе создания - когда мы хотим создать экземпляр объекта, мы не вызываем конструктор класса. Мы просим фабрику сделать это за нас на основе информации, которую мы передаем функции create_shape() .

Плюсы и минусы

Плюсы

Одним из основных преимуществ использования шаблона проектирования Factory Method является то, что наш код становится слабосвязанным, поскольку большинство компонентов нашего кода не знают о других компонентах той же кодовой базы.

В результате получается код, который легко понять и протестировать, а также добавить дополнительные функции к определенным компонентам, не затрагивая и не нарушая работу всей программы.

Шаблон проектирования фабричного метода также помогает поддерживать принцип единой ответственности, в котором классы и объекты, которые обрабатывают определенные функции, приводят к улучшению кода.

Минусы

Создание большего количества классов в конечном итоге приводит к снижению читабельности. В сочетании с абстрактной фабрикой (фабрикой фабрик) код скоро станет многословным, но поддерживаемым.

Заключение

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

Важно отметить, что, как и любой другой шаблон проектирования, он подходит только для определенных ситуаций, а не для каждого сценария разработки. Оценка ситуации имеет решающее значение перед принятием решения о реализации шаблона проектирования фабричного метода, чтобы воспользоваться преимуществами этого шаблона.

comments powered by Disqus