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

El método compuesto es un patrón de diseño estructural que describe un grupo de objetos que se tratan de la misma manera que una sola instancia del mismo tipo de objetos. El propósito del método compuesto es componer objetos en estructuras de tipo árbol para representar las jerarquías total-parcial.

Una de las principales ventajas de usar el método compuesto es que, en primer lugar, le permite componer los objetos en la estructura de árbol y luego trabajar con estas estructuras como un objeto individual o una entidad.

Estructura de árbol compuesto

Estructura de árbol compuesto

Las operaciones que puede realizar en todos los objetos compuestos a menudo tienen la relación del mínimo común denominador.

El Patrón Compuesto tiene cuatro participantes:

Participantes-Compuesto-Métodos

Participantes-Compuesto-Método

  • Componente: el componente ayuda a implementar el comportamiento predeterminado de la interfaz común a todas las clases, según corresponda. Declara la interfaz de los objetos en la composición y para acceder y administrar sus componentes secundarios.
  • Hoja: Define el comportamiento de los objetos primitivos en la composición. Representa el objeto hoja en la composición.
  • Compuesto: almacena el componente hijo e implementa operaciones relacionadas con el hijo en la interfaz del componente.
  • Cliente: Se utiliza para manipular los objetos de la composición a través de la interfaz del componente.

Problema sin utilizar el método compuesto

Imagine que estamos estudiando una estructura organizacional que consta de Gerentes Generales, Gerentes y Desarrolladores. Un Gerente General puede tener muchos Gerentes trabajando debajo de él y un Gerente puede tener muchos desarrolladores debajo de él.
Supongamos que tiene que determinar el salario total de todos los empleados. Entonces, ¿cómo determinarías eso?

Un desarrollador ordinario definitivamente probará el enfoque directo, revisará a cada empleado y calculará el salario total. ¿Parece fácil? no así cuando se trata de la implementación. Porque tenemos que saber las clases de todos los empleados Gerente General, Gerente y Desarrolladores.
Incluso parece una tarea imposible de calcular a través de un enfoque directo en la estructura basada en árboles.

Solución usando el Método Compuesto

Una de las mejores soluciones al problema descrito anteriormente es usar el método compuesto al trabajar con una interfaz común que declara un método para calcular el salario total.
Por lo general, utilizaremos el método compuesto siempre que tengamos «compuestos que contengan componentes, cada uno de los cuales podría ser un compuesto».

Compuesto-Ejecución-Ejemplo

Ejemplo de funcionamiento compuesto

"""Here we attempt to make an organizational hierarchy with sub-organization,
 which may have subsequent sub-organizations, such as:
GeneralManager                                   [Composite]
      Manager1                                   [Composite]
              Developer11                        [Leaf]
              Developer12                        [Leaf]
      Manager2                                   [Composite]
              Developer21                        [Leaf]
              Developer22                        [Leaf]"""
  
class LeafElement:
  
    '''Class representing objects at the bottom or Leaf of the hierarchy tree.'''
  
    def __init__(self, *args):
  
        ''''Takes the first positional argument and assigns to member variable "position".'''
        self.position = args[0]
  
    def showDetails(self):
  
        '''Prints the position of the child element.'''
        print("\t", end ="")
        print(self.position)
  
  
class CompositeElement:
  
    '''Class representing objects at any level of the hierarchy
     tree except for the bottom or leaf level. Maintains the child
      objects by adding and removing them from the tree structure.'''
  
    def __init__(self, *args):
  
        '''Takes the first positional argument and assigns to member
         variable "position". Initializes a list of children elements.'''
        self.position = args[0]
        self.children = []
  
    def add(self, child):
  
        '''Adds the supplied child element to the list of children
         elements "children".'''
        self.children.append(child)
  
    def remove(self, child):
  
        '''Removes the supplied child element from the list of
        children elements "children".'''
        self.children.remove(child)
  
    def showDetails(self):
  
        '''Prints the details of the component element first. Then,
        iterates over each of its children, prints their details by
        calling their showDetails() method.'''
        print(self.position)
        for child in self.children:
            print("\t", end ="")
            child.showDetails()
  
  
"""main method"""
  
if __name__ == "__main__":
  
    topLevelMenu = CompositeElement("GeneralManager")
    subMenuItem1 = CompositeElement("Manager1")
    subMenuItem2 = CompositeElement("Manager2")
    subMenuItem11 = LeafElement("Developer11")
    subMenuItem12 = LeafElement("Developer12")
    subMenuItem21 = LeafElement("Developer21")
    subMenuItem22 = LeafElement("Developer22")
    subMenuItem1.add(subMenuItem11)
    subMenuItem1.add(subMenuItem12)
    subMenuItem2.add(subMenuItem22)
    subMenuItem2.add(subMenuItem22)
  
    topLevelMenu.add(subMenuItem1)
    topLevelMenu.add(subMenuItem2)
    topLevelMenu.showDetails()

Producción:

GeneralManager
    Manager1
        Developer11
        Developer12
    Manager2
        Developer22
        Developer22

Diagrama de clases del método compuesto

El siguiente es el diagrama de clases general para el método compuesto :

Clase-Diagrama-Compuesto-Método

Clase-diagrama-compuesto-método

Ventajas

  • Principio Abierto/Cerrado: Como se permite la introducción de nuevos elementos, clases e interfaces en la aplicación sin romper el código existente del cliente, definitivamente sigue el Principio Abierto/Cerrado
  • Menos consumo de memoria: aquí tenemos que crear menos cantidad de objetos en comparación con el método ordinario, lo que seguramente reduce el uso de memoria y también logra mantenernos alejados de los errores relacionados con la memoria.
  • Tiempo de ejecución mejorado: crear un objeto en Python no lleva mucho tiempo, pero aún así podemos reducir el tiempo de ejecución de nuestro programa compartiendo objetos.
  • Flexibilidad: proporciona flexibilidad de estructura con una clase o interfaz manejable, ya que define jerarquías de clases que contienen objetos primitivos y complejos.

Desventajas

  • Restricción de los componentes: el método compuesto hace que sea más difícil restringir el tipo de componentes de un compuesto. No se prefiere utilizar cuando no desea representar una jerarquía total o parcial de los objetos.
  • Estructura de árbol general: el método compuesto producirá el árbol general general, una vez que se defina la estructura del árbol.
  • Sistema de tipos del lenguaje: Como no está permitido usar el sistema de tipos del lenguaje de programación, nuestro programa debe depender de las verificaciones en tiempo de ejecución para aplicar las restricciones.

Aplicabilidad

  • Requisito de la estructura de árbol anidado: es muy recomendable utilizar el método compuesto cuando necesite producir la estructura anidada del árbol que nuevamente incluye los objetos de hojas y otros contenedores de objetos.
  • Editor de gráficos: podemos definir una forma en tipos, ya sea simple , por ejemplo, una línea recta o compleja, por ejemplo, un rectángulo. Dado que todas las formas tienen muchas operaciones comunes, como representar la forma en la pantalla, se puede usar un patrón compuesto para permitir que el programa trate todas las formas de manera uniforme.

Leer más: Método compuesto 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 *