Método puente: patrones de diseño de Python

El método puente es un patrón de diseño estructural que nos permite separar las abstracciones específicas de la implementación y las abstracciones independientes de la implementación entre sí y se pueden desarrollar considerando como entidades únicas.
El método puente siempre se considera como uno de los mejores métodos para organizar la jerarquía de clases.

Bridge-Method

Método puente

Elementos del patrón de diseño de puente

  • Abstracción: Es el núcleo del Patrón de Diseño de Puente y proporciona la referencia al implementador.
  • Abstracción refinada: extiende la abstracción a un nuevo nivel donde toma los detalles más finos un nivel por encima y oculta el elemento más fino de los implementadores.
  • Implementador: Define la interfaz para las clases de implementación. Esta interfaz no necesita corresponder directamente a la interfaz de abstracción y puede ser muy diferente.
  • Implementación concreta: A través de la implementación concreta, implementa el implementador anterior.

Problema sin usar el Método Bridge

Considere la siguiente clase Cuboid que tiene tres atributos llamados longitud, anchura y altura y tres métodos llamados ProducewithAPI1(), ProduceWithAPI2() y expand()
De estos, los métodos de producción son específicos de la implementación, ya que tenemos dos API de producción y un método, es decir, el método expand() es independiente de la implementación. 

Hasta ahora, solo tenemos dos métodos específicos de implementación y un método independiente de la implementación, pero cuando la cantidad aumente (por supuesto, en un proyecto a gran escala), los desarrolladores tendrán problemas para manejar las cosas.
 

Problem-Bridge-Method

Problema-Puente-Método

Nota: El siguiente código se escribe sin usar el método Bridge.

Python3

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

Solución usando el método Bridge

Ahora veamos la solución para el problema anterior. El método puente es una de las mejores soluciones para este tipo de problemas. Nuestro objetivo principal es separar los códigos de las abstracciones específicas de la implementación y las abstracciones independientes de la implementación .

Solution-Bridge-method

Solución-Puente-Método

Nota: el siguiente código está escrito usando el método Bridge

Python3

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

Diagrama UML del método puente

El siguiente es el diagrama UML para Bridge Method
 

UML-Diagram-bridge-Method

UML-diagram-Bridge-Method

ventajas

  • Principio de responsabilidad única: el método puente sigue claramente el principio de responsabilidad única, ya que desvincula una abstracción de su implementación para que las dos puedan variar de forma independiente.
  • Principio Abierto/Cerrado: No viola el principio Abierto/Cerrado porque en cualquier momento podemos introducir las nuevas abstracciones e implementaciones independientemente unas de otras
  • Característica independiente de la plataforma: Bridge Method se puede usar fácilmente para implementar las características independientes de la plataforma.

Desventajas

  • Complejidad: nuestro código puede volverse complejo después de aplicar el método Bridge porque nos estamos entrometiendo en nuevas clases e interfaces de abstracción.
  • Indirección doble: el método de puente puede tener un ligero impacto negativo en el rendimiento porque la abstracción necesita pasar mensajes junto con la implementación para que se ejecute la operación.
  • Interfaces con una sola implementación: si solo tenemos interfaces limitadas, entonces no hay problema, pero si tiene un conjunto de interfaces explotado con una implementación mínima o solo una, se vuelve difícil de administrar.

Aplicabilidad

  • Enlace en tiempo de ejecución: generalmente, el método Bridge se usa para proporcionar el enlace en tiempo de ejecución de la implementación, aquí el enlace en tiempo de ejecución se refiere a lo que podemos llamar un método en tiempo de ejecución en lugar de en tiempo de compilación.
  • Clases de mapeo: el método puente se utiliza para mapear las jerarquías de clases ortogonales
  • Entorno de interfaz de usuario: se utiliza una aplicación de la vida real del método Bridge en la definición de formas en un entorno de interfaz de usuario

Leer más: Método Bridge en Java
 

Publicación traducida automáticamente

Artículo escrito por chaudhary_19 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *