Паттерн проектирования Мост на Python.

Паттерн Мост (Bridge) — это структурный паттерн проектирования, который позволяет нам отделить абстракции от реализаций и сделать их независимыми друг от друга. В результате абстракции и реализации могут разрабатываться как отдельные сущности. Паттерн Мост считается одним из лучших методов организации иерархии классов. Но давайте поподробнее разберем, что всё это значит.

Элементы паттерна Мост

  • Abstraction (абстракция). Это ядро ​​паттерна Мост. Она предоставляет ссылку на Implementer.
  • Refined Abstraction (расширенная абстракция) содержит различные вариации управляющей логики, наследуется от Abstraction и расширяет унаследованный интерфейс.
  • Implementer (реализатор). Определяет базовый интерфейс для конкретных реализаций. Этот интерфейс не обязательно должен напрямую соответствовать интерфейсу абстракции. Более того, он может сильно отличаться от него.
  • Concrete Implementation (конкретная реализация) наследуется от Implementer.
Паттерн проектирования Мост на Python.

Английский для программистов

Наш телеграм канал с тестами по английскому языку для программистов. Английский это часть карьеры программиста. Поэтому полезно заняться им уже сейчас

Подробнее×Какую проблему решает паттерн Мост?

Давайте представим, что у нас есть класс Cuboid (параллелепипед), который имеет три атрибута: length (длина), breadth (ширина) и height (высота). Также он имеет три метода: ProducewithAPI()ProduceWithAPI2() и expand().

Два метода зависят от реализации, поскольку у нас есть два API, а один метод — expand() — не зависит.

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

Паттерн проектирования Мост на Python.

Следующий код написан без использования паттерна Мост:


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()

Решение проблемы при помощи паттерна Мост

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

Наша основная задача — разделить код абстракции и реализации. В результате мы получим следующую структуру:

Паттерн проектирования Мост на Python.

Следующий код написан с использованием паттерна Мост:

"""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-диаграмма паттерна Мост

Вот так будет выглядеть UML-диаграмма паттерна Мост:

Паттерн проектирования Мост на Python.

Преимущества применения паттерна Мост

  1. Принцип единой ответственности. Паттерн Мост четко следует принципу единой ответственности: он отделяет абстракцию от ее реализации, чтобы они могли видоизменяться независимо друг от друга.
  2. Принцип открытости/закрытости. Данный паттерн не нарушает принцип открытости/закрытости. Поскольку абстракция и реализация не зависят друг от друга, мы в любой момент можем ввести новые абстракции и реализации.
  3. Кроссплатформенность. Паттерн Мост можно легко использовать для реализации независимых от платформы функций и создания кроссплатформенных приложений.

Недостатки применения паттерна Мост

  1. Сложность. При использовании Моста наш код может усложниться, потому что мы вводим новые классы абстракций и реализаций.
  2. Снижение производительности. Применение Моста может немного ухудшить производительность.
  3. Интерфейсы только с одной реализацией. Если у нас ограниченное количество интерфейсов, то это не страшно. Но если у нас раздутый набор интерфейсов (абстракций) с минимальным количеством реализаций или вообще с одной реализацией, ими становится крайне трудно управлять.

Применение паттерна Мост

  • Динамическое связывание. Обычно паттерн Мост используется для обеспечения динамического связывания реализации. Это означает, что мы можем вызывать метод во время выполнения, а не во время компиляции.
  • Сопоставление классов. Данный паттерн также используется для сопоставления ортогональных иерархий классов.
  • UI-окружение. Мост используется при определении очертаний пользовательского интерфейса.

Заключение

Итак, мы познакомились с паттерном проектирования Мост (Bridge). Теперь вы знаете, какую проблему он решает и как применяется. Кроме того, мы разобрали преимущества и недостатки данного паттерна.

Надеемся, данная статья была вам полезна! Успехов в написании кода!

https://t.me/data_analysis_ml

https://t.me/pythonl

+1
0
+1
0
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *