O objetivo do uso do padrão flyweight é evitar a inicialização desnecessária de objetos e, assim, economizar espaço. Conforme definido pelo GOF , um objeto pode ter dois estados, o intrínseco e o extrínseco:
- Estado intrínseco: é armazenado no peso mosca; consiste em informações independentes no contexto de pesos livres, tornando-as compartilháveis.
- Estado extrínseco: depende e varia de acordo com o contexto do peso da mosca e, portanto, não pode ser compartilhado. Os objetos do cliente são responsáveis por passar o estado extrínseco para o peso da mosca quando necessário.
Supondo que desejamos desenvolver um aplicativo simples de editor de texto em que cada coluna contenha todas as linhas do texto e a linha possa conter caracteres.
O dilema aqui é como projetar a classe Character. O char c
dentro da classe Character deve ser o objeto principal (estado intrínseco). No entanto, um caractere pode ter uma fonte e um tamanho (estado extrínseco); portanto, precisamos armazenar seu estado extrínseco na linha (cliente) e acessá-lo quando necessário. Para esse fim, são criadas duas listas que armazenam as fontes e os tamanhos.
Seguindo o padrão Flyweight, o caractere agora é reutilizável e os objetos estão sendo referenciados a partir de uma lista específica de objetos (o pool de flyweight) que contém todos os símbolos ASCII ( Character
objetos).
Aqui está o que eu descrevi visualmente:
Para imprimir 'olá', Character
são necessários apenas 4 objetos, em vez de 5. Depois que a fonte é alterada, nenhum novo objeto é necessário; observe que isso não seria possível se tivéssemos armazenado o estado extrínseco na classe Character, por exemplo,
class Character
{
char c;
int Size;
Font font;
....
}
A aplicação desse padrão em grandes conjuntos de dados levaria a otimizações significativas na complexidade da memória do aplicativo e na reutilização do objeto.