Tech Writers

Padrão de Projeto Composite: O que é, prós e contras e como implementar?

5 minutos

Se você atua com projetos de software e já teve a necessidade de tratar objetos individuais e coleções de objetos de forma uniforme, o padrão de projeto Composite vai te ajudar.

Descubra a seguir como o padrão Composite auxilia na criação de interfaces de usuário mais intuitivas e no processamento de árvores de objetos de forma eficiente.

Neste artigo, convidamos você a explorar os benefícios desse padrão, que simplifica estruturas hierárquicas e oferece maior flexibilidade na manipulação de elementos.

Confira abaixo o que é o Composite, quais suas vantagens e desvantagens e veja um exemplo prático da sua implementação.

O que é o Composite?

O Composite é um padrão de projeto estrutural que permite tratar de maneira uniforme os objetos individuais e composições de objetos, formando uma estrutura hierárquica.

Ele é o quarto padrão desta categoria apresentado pela “Gang of Four” (GoF).

Como os próprios autores colocam, a intenção oficial deste padrão é “compor objetos em estruturas de árvore para representar hierarquias partes-todo”.

Com o Composite, um objeto individual e um grupo de objetos são tratados da mesma maneira, pois ambos implementam uma interface comum.

Como funciona o padrão de projeto Composite?

Dentro do padrão Composite, encontramos uma classe abstrata conhecida como “Componente”, que estabelece uma interface compartilhada para objetos individuais e grupos de objetos.

Os objetos individuais são representados por uma classe concreta que implementa o Componente, enquanto os grupos de objetos são representados por uma classe composta que também implementa o Componente.

A estrutura hierárquica é criada através da composição, na qual um grupo de objetos pode incluir outros objetos individuais ou grupos de objetos. Essa estrutura permite a realização de interações recursivas, e dessa forma possibilita a aplicação de operações a todos os objetos na hierarquia.

O padrão Composite é ideal para quando há a necessidade de tratar objetos individuais e coleções de objetos de forma homogênea, simplificando o código e conferindo maior flexibilidade.

Seu uso é comum em interfaces de usuário, processamento de árvores e outras estruturas hierárquicas.

Como é a implementação do Composite?

Para entender melhor a implementação do Composite, vamos analisar o exemplo a seguir:

Em um supermercado, você possui duas formas de comprar um refrigerante:

  • É possível comprar a unidade
  • Ou comprar um fardo com 12 unidades

Aqui, nós temos um Composite: a noção de que o fardo (estrutura) se comporta como um produto, e que ele pode dizer seu preço delegando o seu valor, somando assim os custos das unidades filhas e utilizando como seu próprio.

Claro, o cenário acima só faz sentido se o fardo não possuir um valor fixo, e sim que seu valor se resume no total de unidades que há dentro do mesmo.

Vejamos um código do cenário descrito (no caso, utilizando Java para exemplificar):

No exemplo acima, definimos uma interface Produto, que será implementada tanto pela unidade de “refrigerante”, quanto pelo fardo. O método em comum que será implementado por eles, no nosso caso, é o getValor().

O refrigerante, por sua vez, possui o valor e um nome. A implementação do getValor(), por ser uma única unidade, apenas retorna o seu próprio valor.

Acima temos o fardo de refrigerantes, atuando como Composite, seu “valor” é delegado para as unidades que há dentro dele.

Ou seja, se houver 5 unidades de refrigerante, cada uma com um valor “5”, o valor do fardo será de 25.

O interessante neste design pattern é que a complexidade desse tipo de estrutura não acaba por aí.

Como a classe FardoDeRefrigerante possui uma lista dentro de si do tipo Produto, ela é capaz de suportar até mesmo outros fardos dentro de si mesma.

Exemplo da Estrutura de um Composite

Apesar de o “fardo de refrigerante” não ser o melhor exemplo nesse caso, podemos imaginar uma caixa dentro de outra caixa, e cada uma delas com produtos de diferentes valores dentro de si, as caixas internas totalizaram o valor dos produtos internos, e a caixa externa totalizaria o valor das caixas internas, parecendo muito com a estrutura abaixo:

Exemplo de como a estrutura de um composite pode ficar. Fonte: “Padrões de Projetos: Soluções Reutilizáveis de Software Orientados a Objetos”

Normalmente utiliza-se o padrão de projeto Composite, por exemplo, para rodar uma bateria de validações em cima de um objeto.

Enquanto o Decorator serve para estender funcionalidades dentro de uma classe já existente, sem alterar a classe original e preservando os princípios SOLID.

A forma de implementação pode variar bastante dependendo de como que você utiliza, mas o importante é conhecer o padrão e saber quando encaixá-lo no seu sistema.

Não siga à risca os diagramas propostos pela GoF, ou os exemplos citados, adeque-os de acordo com suas necessidades e situações.

Quando usar o padrão de projeto Composite?

Aplica-se o padrão de projeto Composite nas situações em que há uma estrutura hierárquica de objetos e quando se deseja tratar objetos individuais e grupos de objetos de forma uniforme, simplificando o código e fornecendo maior flexibilidade.

Aqui estão algumas situações de exemplo do uso do padrão Composite:

  • Estruturas Hierárquicas: 

O padrão Composite é ideal para lidar com estruturas hierárquicas, como árvores ou grafos, onde os nós podem ser objetos individuais ou grupos de objetos.

  • Modelagem de Interface de Usuário: 

É comum utilizar o padrão Composite na construção de interfaces de usuário, especialmente quando há elementos que podem conter outros elementos, como menus, botões e painéis.

  • Processamento de Documentos:

O Composite pode ser útil para tratar elementos como documentos com seções, parágrafos, listas, etc, de forma uniforme.

  • Manipulação de Gráficos:

Se você precisa lidar com elementos gráficos, como formas, linhas e grupos de formas, o Composite permite tratá-los de maneira uniforme e facilita a aplicação de operações a todos os elementos.

  • Implementação de Estruturas de Dados:

Também é possível aplicar o Composite na implementação de estruturas de dados como arrays, listas e matrizes, em que tratam-se os elementos individuais e os grupos de elementos de forma semelhante.

Quais os prós e contras de usar o Composite?

Confira os principais prós e contras do Composite:

PrósContras
Simplifica a estrutura hierárquicaPode ter impacto na eficiência em estruturas muito grandes
Oferece flexibilidade na manipulação de objetos e operações recursivasPode exigir maior esforço de design e implementação inicial
Promove reuso do códigoRequer uma interface comum bem definida

No entanto, é importante lembrar que os prós e contras do Composite podem variar dependendo do contexto e dos requisitos específicos do projeto.

Portanto, é essencial considerar cuidadosamente esses aspectos antes de decidir utilizar o design pattern Composite.

E você já sabia como implementar o Composite? Aproveite e confira outros conteúdos de tecnologia no Tech Writers.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *