Tenho estudado padrões de design e me deparei com o padrão de peso da mosca. Eu tenho tentado ver oportunidades para usar o padrão nos meus aplicativos, mas estou tendo problemas para ver como usá-lo. Além disso, quais são alguns sinais de que um padrão de peso de mosca está sendo usado quando leio o código de outras pessoas?
De acordo com a definição, diz:
Use o compartilhamento para oferecer suporte a um grande número de objetos refinados com eficiência.
Se eu li certo Dicionários e Hashtables podem ser instâncias de pesos de mosca, isso está correto?
Desde já, obrigado.
design-patterns
Jeremy E
fonte
fonte
Respostas:
Um exemplo está nas bibliotecas Java. Java possui tipos primitivos (por exemplo
int
, que é um número inteiro de 32 bits) e invólucros para eles (por exemploInteger
, que envolveint
). Existem métodos para "int
encaixar " um em umInteger
e desmarcar umInteger
em umint
. Os wrappers são necessários porque os tipos primitivos não são objetos e, portanto, não podem, por exemplo, ser usados como chaves emMap
s ou colocados emCollection
s.O método de boxe usa uma matriz de objetos flyweight como um tipo de cache para
Integer
s correspondente aint
valores entre -128 e 127. Como esses são os valores com maior probabilidade de serem usados como chaves ou colocados em coleções, reduz a alocação e o uso de memória. (Se houver 5000000Integer
s representando o valor 0 flutuando, isso usa 5000000 vezes mais memória que a reutilização da instância flyweight).fonte
Gráficos. Normalmente, uma imagem raster (que é a espinha dorsal da maioria dos gráficos de computador no nível do consumidor) é barata em termos de CPU, mas dispendiosa em termos de memória (o que é bom porque a memória é barata, mas a CPU é cara). Se essa imagem rasterizada deve ser repetida várias vezes na renderização de uma interface do usuário maior (de ícones em um aplicativo da GUI do Windows a caracteres de uma fonte em um processador de texto, a texturas nas superfícies de um jogo em 3D), faz muito sentido carregue a imagem na memória uma vez e aponte-a simplesmente usando objetos muito simples que são baratos de fabricar e que, eles próprios, não consomem muita memória. Um sprite, que é simplesmente um ponto no espaço gráfico no qual uma imagem deve ser exibida, é apenas um ponto 3D e um ponteiro de memória para o primeiro pixel da imagem a ser usado. Talvez também inclua as dimensões da parte do arquivo de imagem do sprite a ser usada, em termos gráficos ou de memória. Todas essas informações são muito baratas para mudar, digamos, para alterar a imagem ou o local do sprite, e isso pode ser feito sem carregar uma nova imagem a cada vez, aumentando drasticamente o desempenho do programa subjacente para manipular e exibir as partes apropriadas do imagens apropriadas para renderizar uma "cena" completa da interface do usuário.
fonte
As
Character
instâncias de intervalo ASCII no Smalltalk são pesos livres.Quando você avalia algo como
Character space
,Character class >> #value:
executa:A variável de classe
CharacterTable
é inicializada assim:Portanto, quando você cria uma String, o intervalo ASCII
Character
seráCharacterTable
gerado em vez de ser criado sempre.fonte
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:
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,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.
fonte