Patrón de diseño compuesto – Part 1

El patrón compuesto es un patrón de diseño de particiones y describe un grupo de objetos que se trata de la misma manera que una única instancia del mismo tipo de objeto. La intención de un compuesto es «componer» objetos en estructuras de árbol para representar jerarquías de parte-todo. Le permite tener una estructura de árbol y pedirle a cada Node en la estructura de árbol que realice una tarea.

  • Como lo describe Gof, “Componga objetos en una estructura de árbol para representar jerarquías de parte-todo . Composite permite al cliente tratar objetos individuales y composiciones de objetos de manera uniforme”.
  • Cuando se trata de datos estructurados en árbol, los programadores a menudo tienen que discriminar entre un Node hoja y una rama. Esto hace que el código sea más complejo y, por lo tanto, propenso a errores. La solución es una interfaz que permite tratar de manera uniforme objetos complejos y primitivos.
  • En la programación orientada a objetos, un compuesto es un objeto diseñado como una composición de uno o más objetos similares, todos exhibiendo una funcionalidad similar. Esto se conoce como una relación «tiene un» entre objetos.
  • El concepto clave es que puede manipular una sola instancia del objeto tal como manipularía un grupo de ellos. Las operaciones que puede realizar en todos los objetos compuestos a menudo tienen una relación de mínimo común denominador.
    El Patrón Compuesto tiene cuatro participantes:

  1. Componente: el componente declara la interfaz para los objetos en la composición y para acceder y administrar sus componentes secundarios. También implementa el comportamiento predeterminado para la interfaz común a todas las clases según corresponda.
  2. Hoja: la hoja define el comportamiento de los objetos primitivos en la composición. Representa objetos de hoja en la composición.
  3. Compuesto: el compuesto almacena componentes secundarios e implementa operaciones relacionadas con los elementos secundarios en la interfaz del componente.
  4. Cliente: el cliente manipula los objetos de la composición a través de la interfaz del componente.

El cliente utiliza la interfaz de clase de componente para interactuar con objetos en la estructura de composición. Si el destinatario es una hoja, la solicitud se gestiona directamente. Si el destinatario es un compuesto, generalmente reenvía la solicitud a sus componentes secundarios, posiblemente realizando operaciones adicionales antes y después del reenvío.

ejemplo de la vida real

En una organización, tiene gerentes generales y bajo gerentes generales, puede haber gerentes y bajo gerentes puede haber desarrolladores. Ahora puede establecer una estructura de árbol y pedirle a cada Node que realice una operación común como getSalary().
El patrón de diseño compuesto trata cada Node de dos maneras:
1) Compuesto : compuesto significa que puede tener otros objetos debajo.
2) hoja : hoja significa que no tiene objetos debajo.

Estructura de árbol:

Tree
The above figure shows a typical Composite object structure. As you can see, there can be many children to a single parent i.e. Composite, but only one parent per child.

Componente de interfaz.java

public interface Employee
{
    public void showEmployeeDetails();
}

Hoja.java

public class Developer implements Employee
{
    private String name;
    private long empId;
    private String position;
  
    public Developer(long empId, String name, String position)
    {
        this.empId = empId;
        this.name = name;
                this.position = position;
    }
      
    @Override
    public void showEmployeeDetails() 
    {
        System.out.println(empId+" " +name+);
    }
}

Hoja.java

public class Manager implements Employee
{
    private String name;
    private long empId;
        private String position;
  
    public Manager(long empId, String name, String position)
    {
        this.empId = empId;
        this.name = name;
                this.position = position;
    }
      
    @Override
    public void showEmployeeDetails() 
    {
        System.out.println(empId+" " +name);
    }
}

Compuesto.java

import java.util.ArrayList;
import java.util.List;
  
public class CompanyDirectory implements Employee
{
    private List<Employee> employeeList = new ArrayList<Employee>();
       
    @Override
    public void showEmployeeDetails() 
    {
        for(Employee emp:employeeList)
        {
            emp.showEmployeeDetails();
        }
    }
       
    public void addEmployee(Employee emp)
    {
        employeeList.add(emp);
    }
       
    public void removeEmployee(Employee emp)
    {
        employeeList.remove(emp);
    }
}

Cliente.java

public class Company
{
    public static void main (String[] args)
    {
        Developer dev1 = new Developer(100, "Lokesh Sharma", "Pro Developer");
        Developer dev2 = new Developer(101, "Vinay Sharma", "Developer");
        CompanyDirectory engDirectory = new CompanyDirectory();
        engDirectory.addEmployee(dev1);
        engDirectory.addEmployee(dev2);
          
        Manager man1 = new Manager(200, "Kushagra Garg", "SEO Manager");
        Manager man2 = new Manager(201, "Vikram Sharma ", "Kushagra's Manager");
          
        CompanyDirectory accDirectory = new CompanyDirectory();
        accDirectory.addEmployee(man1);
        accDirectory.addEmployee(man2);
      
        CompanyDirectory directory = new CompanyDirectory();
        directory.addEmployee(engDirectory);
        directory.addEmployee(accDirectory);
        directory.showEmployeeDetails();
    }
}

Diagrama UML para el patrón de diseño compuesto:

Composite-Design-UML

Código de ejecución completo para el ejemplo anterior:

// A Java program to demonstrate working of
// Composite Design Pattern with example 
// of a company with different
//  employee details
  
import java.util.ArrayList;
import java.util.List;
  
  
// A common interface for all employee
interface Employee
{
    public void showEmployeeDetails();
}
  
class Developer implements Employee
{
    private String name;
    private long empId;
    private String position;
      
    public Developer(long empId, String name, String position)
    {
        // Assign the Employee id,
        // name and the position
        this.empId = empId;
        this.name = name;
        this.position = position;
    }
      
    @Override
    public void showEmployeeDetails() 
    {
        System.out.println(empId+" " +name+ " " + position );
    }
}
  
class Manager implements Employee
{
    private String name;
    private long empId;
    private String position;
   
    public Manager(long empId, String name, String position)
    {
        this.empId = empId;
        this.name = name;
        this.position = position;
    }
       
    @Override
    public void showEmployeeDetails() 
    {
        System.out.println(empId+" " +name+ " " + position );
    }
}
  
  
// Class used to get Employee List
// and do the opertions like 
// add or remove Employee
  
class CompanyDirectory implements Employee
{
    private List<Employee> employeeList = new ArrayList<Employee>();
        
    @Override
    public void showEmployeeDetails() 
    {
        for(Employee emp:employeeList)
        {
            emp.showEmployeeDetails();
        }
    }
        
    public void addEmployee(Employee emp)
    {
        employeeList.add(emp);
    }
        
    public void removeEmployee(Employee emp)
    {
        employeeList.remove(emp);
    }
}
  
// Driver class
public class Company
{
    public static void main (String[] args)
    {
        Developer dev1 = new Developer(100, "Lokesh Sharma", "Pro Developer");
        Developer dev2 = new Developer(101, "Vinay Sharma", "Developer");
        CompanyDirectory engDirectory = new CompanyDirectory();
        engDirectory.addEmployee(dev1);
        engDirectory.addEmployee(dev2);
           
        Manager man1 = new Manager(200, "Kushagra Garg", "SEO Manager");
        Manager man2 = new Manager(201, "Vikram Sharma ", "Kushagra's Manager");
           
        CompanyDirectory accDirectory = new CompanyDirectory();
        accDirectory.addEmployee(man1);
        accDirectory.addEmployee(man2);
       
        CompanyDirectory directory = new CompanyDirectory();
        directory.addEmployee(engDirectory);
        directory.addEmployee(accDirectory);
        directory.showEmployeeDetails();
    }
}

Producción :

100 Lokesh Sharma Pro Developer
101 Vinay Sharma Developer
200 Kushagra Garg SEO Manager
201 Vikram Sharma  Kushagra's Manager

¿Cuándo usar el patrón de diseño compuesto?

El patrón compuesto debe usarse cuando los clientes necesitan ignorar la diferencia entre las composiciones de objetos y los objetos individuales. Si los programadores descubren que están usando múltiples objetos de la misma manera y, a menudo, tienen un código casi idéntico para manejar cada uno de ellos, entonces el compuesto es una buena opción, es menos complejo en esta situación tratar los primitivos y los compuestos como homogéneos.

  1. Una menor cantidad de objetos reduce el uso de la memoria y logra mantenernos alejados de errores relacionados con la memoria como java.lang.OutOfMemoryError .
  2. Aunque crear un objeto en Java es realmente rápido, aún podemos reducir el tiempo de ejecución de nuestro programa compartiendo objetos.

¿Cuándo no usar el patrón de diseño compuesto?

  1. El patrón de diseño compuesto hace que sea más difícil restringir el tipo de componentes de un compuesto. Por lo tanto, no debe usarse cuando no desee representar una jerarquía total o parcial de objetos.
  2. El patrón de diseño compuesto puede hacer que el diseño sea demasiado general. Hace más difícil restringir los componentes de un compuesto. A veces desea que un compuesto tenga solo ciertos componentes. Con Composite, no puede confiar en el sistema de tipos para aplicar esas restricciones por usted. En su lugar, tendrá que utilizar comprobaciones en tiempo de ejecución.

Lectura adicional: método compuesto en Python

Este artículo es una contribución de Saket Kumar . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 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 *