Design Pattern: Flyweight

Vinicius Climaco
6 min readOct 31, 2022

--

Neste dia das bruxas, não trago doces e tão pouco seriam travessuras, mas lhe entrego mais um padrão de projeto! :)

Chegamos ao nosso último padrão da família Estrutural e também ao vigésimo artigo que publico aqui no Medium, agradeço a você que vem me acompanhando semanalmente.

Desta vez iremos falar sobre um padrão que tem um nome um tanto quanto ‘diferente’, Flyweight que em sua tradução literal seria peso-mosca, por este motivo deixo uma foto de um lutador brasileiro que foi campeão do UFC exatamente na categoria peso-mosca, acredito que estas analogias caminharão com seu pensamento no momento de lembrar dos padrões que estamos estudando.

Flyweight Champion UFC

Conceito GoF

Use o compartilhamento para suportar grandes quantidades de objetos, de granularidade fina, de maneira eficiente.

Para resumir, saiba que este padrão usa o compartilhamento para dar suporte a muitos objetos refinados com eficiência, algumas vezes precisamos lidar com muitos objetos que são semelhantes por essência, porém não idênticos.

Sendo assim, a restrição está em não poder criar todos eles justamente por conta do uso de recursos, principalmente memória, com isso o Padrão Flyweight é perfeito para lidar em cenários de repetição de objetos.

Um tipo de cópia simultânea, esta é a essência do Flyweight, apesar de ser um compartilhamento, cada situação atua como um objeto independente — é indistinguível de uma instância do objeto que não é compartilhada.

Com isso, o Flyweight não pode fazer suposição sobre o contexto em que opera, no qual, o conceito chave aqui é a distinção entre o estado intrínseco e extrínseco, segue:

  • Estado Intrínseco — são propriedades que não mudam (imutáveis), ou seja, podendo ser compartilhado.
  • Estado Extrínseco — são propriedades que mudam de um objeto para o outro, ou seja, cada acesso recebendo novos parâmetros.

Cotidiano

Acredito que você tenha visto ou já tenho ouvido falar do filme 300, na qual conta a história de guerreiros Espartanos e conta com a participação do ator brasileiro Rodrigo Santoro no papel do vilão principal, pois bem nosso exemplo girará em torno deste cenário.

Cena do Filme 300 do ano de 2006.

Na cena acima, veja que temos próximo da foto 5 atores e mais ao fundo incontáveis atores no papel de guerreiros de Esparta, certo? Imagine se o filme tivesse que contratar milhares de guerreiros para uma cena de 10 ou 15 minutos no máximo… teria um custo muito algo, concorda?

Por este motivo existe um efeito de duplicar determinado ator, alterando apenas poucas características mediante efeitos especiais, com isso é investido em computação gráfica e menos em contratações humanas para cenas feito essas que temos aos montes se pensarmos bem, lembre de algum filme que tem uma cena de jogo de futebol por exemplo, agora pense em lotar o Maracanã seriam cerca de 80 mil pessoas para essa cena, difícil não?! Pois é…

Exatamente nestes cenários que temos o padrão Flyweight se encaixando perfeitamente, pois conseguimos “duplicar” utilizando o mesmo objeto com apenas algumas pequenas características sendo alteradas, porém com o consumo ínfimo se compararmos por exemplo criar 80 mil objetos para representar cada torcedor no estádio de futebol.

Diagrama UML

Diagrama UML do Padrão Flyweight

Conforme segue acima, temos o diagrama UML para o padrão Flyweight, abaixo descrevo cada componente.

  • Client — Como de costume temos o Client, que nosso caso é o Program.cs que nada mais é quem fará a referência ao Flyweight.
  • FlyweightFactory — Responsável pela criação e gerenciamento do Flyweight.
  • Flyweight — Interface responsável por definir os membros do objeto Flyweight.
  • UnsharedConcreteFlyweight — Classe concreta não compartilhável, na verdade a implementação deste componente é opcional e normalmente não utilizado.
  • ConcreteFlyweight — Classe concreta compartilhável e obrigatória nos projetos cujo padrão seja Flyweight, pois é a representação do objeto, armazena as propriedades constantes (intrínsecas), conforme visto no diagrama implementa a interface Flyweight.

Implementação

Iremos seguir o nosso exemplo do que foi citado no Cotidiano, pois iremos gerar diversos guerreiros para o exército de Esparta através de nosso exemplo, segue o Diagrama de Classes.

Diagrama de Classes do Padrão Flyweight

Segue abaixo nosso código do projeto para montarmos a representação do padrão Flyweight, na qual queremos gerar dezenas de milhares de guerreiros e crianças no cenário de nosso filme fictício.

IPessoa representando Flyweight
Guerreiro representando ConcreteFlyweight
Crianca representando ConcreteFlyweight
FlyweightFactory

Para uma forma didática escolhi colocar a geração dos nomes e também das armas dentro do Factory, em seu projeto de produção tente distribuir as responsabilidades. Outro ponto a ser citado que utilizei uma biblioteca chamada RandomNameGeneratorLibrary para gerar os nomes das crianças de forma randômica.

Program.cs representando o Client
Resultado final de nosso projeto.

Observe que na primeira vez de cada tipo é informado que está sendo gerado um novo objeto, a partir da segunda vez informamos que estamos utilizando um objeto pré-existente.

Espero que tenha gostado do resultado final de nosso projeto, observe que você criará milhares de guerreiros ou crianças com apenas 2 instâncias em memória, muito interessante não?! Acredito até que você já tenha feito uso deste padrão e talvez não soubesse que este era o Flyweight.

Prós e Contras

Conforme acompanhou em todo artigo, nosso principal ponto positivo seria a redução no uso de memória através do compartilhamento de objetos, através do uso de ‘cache’ temos um ganho também na resposta das requisições e somando estes dois atributos mencionado temos como consequência o aumento de performance. Para ponto negativo observo que é utilizado em questões muito pontuais, na qual o objeto a ser compartilhado deve ter caracteríscas bem similares uns com os outros.

Código Fonte

Baixe já o código fonte em meu GitHub clicando neste link, implemente seus ajustes no padrão Flyweight, evolua o cenário de nosso artigo implementando novos personagens ao exército de Esparta e depois me conte nos comentários.

Finalizando a família Estrutural

Agradeço a você que ficou fim deste artigo e agradeço ainda mais aos que acompanham nossa série e dizer que chegamos ao fim da família Estrutural, estarei realizando uma pausa de duas segunda-feiras sem o nosso já tradicional artigo antes de entrarmos na família Comportamental, portanto estaremos de volta no dia 21 de Novembro (segunda-feira).

Para você que gostou e vem gostando de nossa série de artigos sobre Padrões de Projeto de forma rápida e objetiva, peço que curta, aplauda aqui no Medium ou até mesmo compartilhe com seus amigos e colegas de trabalho/faculdade/comunidade.

Forte abraço e até a próxima…

--

--

Vinicius Climaco

Tech Speaker | Solutions Architect | Microsoft MVP | Aws Community Builder