Паттерн Мост (Bridge) — это структурный паттерн проектирования, который позволяет нам отделить абстракции от реализаций и сделать их независимыми друг от друга. В результате абстракции и реализации могут разрабатываться как отдельные сущности. Паттерн Мост считается одним из лучших методов организации иерархии классов. Но давайте поподробнее разберем, что всё это значит.
Давайте представим, что у нас есть класс Cuboid
(параллелепипед), который имеет три атрибута: length
(длина), breadth
(ширина) и height
(высота). Также он имеет три метода: ProducewithAPI()
, ProduceWithAPI2()
и expand()
.
Два метода зависят от реализации, поскольку у нас есть два API, а один метод — expand()
— не зависит.
Пока у нас всего три метода, все в порядке. Но в масштабируемом проекте их количество может вырасти, и тогда разработчикам станет крайне сложно с ними справляться. Посмотрите, как быстро может разрастись такая структура:
Следующий код написан без использования паттерна Мост:
""" Code without using the bridge method We have a class with three attributes named as length, breadth, and height and three methods named as ProduceWithAPI1(), ProduceWithAPI2(), and expand(). Out of these producing methods are implementation-specific as we have two production APIs""" class Cuboid: class ProducingAPI1: """Implementation Specific Implementation""" def produceCuboid(self, length, breadth, height): print(f'API1 is producing Cuboid with length = {length}, ' f' Breadth = {breadth} and Height = {height}') class ProducingAPI2: """Implementation Specific Implementation""" def produceCuboid(self, length, breadth, height): print(f'API2 is producing Cuboid with length = {length}, ' f' Breadth = {breadth} and Height = {height}') def __init__(self, length, breadth, height): """Initialize the necessary attributes""" self._length = length self._breadth = breadth self._height = height def produceWithAPI1(self): """Implementation specific Abstraction""" objectAPIone = self.ProducingAPI1() objectAPIone.produceCuboid(self._length, self._breadth, self._height) def producewithAPI2(self): """Implementation specific Abstraction""" objectAPItwo = self.ProducingAPI2() objectAPItwo.produceCuboid(self._length, self._breadth, self._height) def expand(self, times): """Implementation independent Abstraction""" self._length = self._length * times self._breadth = self._breadth * times self._height = self._height * times # Instantiate a Cubiod cuboid1 = Cuboid(1, 2, 3) # Draw it using APIone cuboid1.produceWithAPI1() # Instantiate another Cuboid cuboid2 = Cuboid(19, 20, 21) # Draw it using APItwo cuboid2.producewithAPI2()
Теперь давайте посмотрим на решение вышеуказанной проблемы с использованием паттерна Мост. Данный паттерн является одним из лучших решений для такого рода проблем.
Наша основная задача — разделить код абстракции и реализации. В результате мы получим следующую структуру:
Следующий код написан с использованием паттерна Мост:
"""Code implemented with Bridge Method. We have a Cuboid class having three attributes named as length, breadth, and height and three methods named as produceWithAPIOne(), produceWithAPItwo(), and expand(). Our purpose is to separate out implementation specific abstraction from implementation-independent abstraction""" class ProducingAPI1: """Implementation specific Abstraction""" def produceCuboid(self, length, breadth, height): print(f'API1 is producing Cuboid with length = {length}, ' f' Breadth = {breadth} and Height = {height}') class ProducingAPI2: """Implementation specific Abstraction""" def produceCuboid(self, length, breadth, height): print(f'API2 is producing Cuboid with length = {length}, ' f' Breadth = {breadth} and Height = {height}') class Cuboid: def __init__(self, length, breadth, height, producingAPI): """Initialize the necessary attributes Implementation independent Abstraction""" self._length = length self._breadth = breadth self._height = height self._producingAPI = producingAPI def produce(self): """Implementation specific Abstraction""" self._producingAPI.produceCuboid(self._length, self._breadth, self._height) def expand(self, times): """Implementation independent Abstraction""" self._length = self._length * times self._breadth = self._breadth * times self._height = self._height * times """Instantiate a cuboid and pass to it an object of ProducingAPIone""" cuboid1 = Cuboid(1, 2, 3, ProducingAPI1()) cuboid1.produce() cuboid2 = Cuboid(19, 19, 19, ProducingAPI2()) cuboid2.produce()
Вот так будет выглядеть UML-диаграмма паттерна Мост:
Итак, мы познакомились с паттерном проектирования Мост (Bridge). Теперь вы знаете, какую проблему он решает и как применяется. Кроме того, мы разобрали преимущества и недостатки данного паттерна.
Надеемся, данная статья была вам полезна! Успехов в написании кода!
Перевод статьи «Bridge Method – Python Design Patterns».
Pydantic - это мощная библиотека проверки данных и управления настройками для Python, созданная для повышения…
Python предлагает набор библиотек, удовлетворяющих различные потребности в визуализации, будь то академические исследования, бизнес-аналитика или…
В Python для представления данных в двоичной форме можно использовать байты. Из этой статьи вы…
В этой статье рассказывается о том, что такое Werkzeug и как Flask использует его для…
При работе с датами часто возникает необходимость прибавлять к дате или вычитать из нее различные…
В этом руководстве мы рассмотрим, как добавить социальную аутентификацию с помощью GitHub и Google в…