Padrões de Projeto de Software Flyweight Paulo Gomide Departamento de Ciência da Computação Universidade de Itaúna
Sumary
Flyweight Definição Usa compartilhamento para suportar uma grande quantidade de objetos de baixa granularidade de forma eficiente; Um objeto compartilhado, como o próprio padrão, é conhecido por Flyweight;
Motivação Abstrair até o último nível pode ser muito custoso, especialmente em aplicações que utilizam grande número de objetos. Problema Específico Um exemplo real onde o isso acontece é no desenvolvimento de um editor de texto; Se cada caracter é representado por um objeto diferente, pode não haver recursos (memória) sufientes para textos muito grandes.
Motivação
Motivação Solução Flyweight: monta-se um pool de objetos compartilhados ou pool de Flyweights; Dessa forma, cada caracter tem um objeto nesse pool; Com 100 objetos (tabela ASCII) poderíamos montar textos de qualquer tamanho.
Motivação Logicamente existe um objeto para cada ocorrência de um dado caracter no documento.
Motivação Entretanto, fisicamente existe um objeto flyweight para cada caracter e ele aparece em diferentes contextos do documento. Cada ocorrência de um dado caracter referencia a mesma instância daquele caracter no pool de flyweights.
Motivação
Estrutura do Problema Específico
Observações Intuito do Flyweight O padrão procura fatorar as informações comuns a diversos objetos; Desassocia o que é intrínseco do que é extrínseco ao objeto: Intrínseco: inerente, próprio do objeto. Informações independentes de contexto, podendo, por isso, ser compartilhadas. Essas informações são armazenadas no Flyweight; Extrínseco: depende e varia com o contexto, não podendo, por isso, ser compartilhado. Tal estado é armazenado no cliente.
Aplicabilidade Requisitos para se Aplicar o Padrão O uso do padrão Flyweight é indicado quando: Aplicação utiliza grande número de objetos; Custos de armazenamento altos; A maior parte dos estados dos objetos pode ser tornada intrínseca (estados internalizados); Muitos objetos podem ser substituídos por poucos compartilhados; Aplicação não depende da identidade dos objetos. testes de identidade produzirão o valor verdadeiro para objetos conceitualmente distintos.
Estrutura do Problema Geral
Estrutura do Problema Geral
Participantes do Padrão Client Mantém uma referência ao flyweight; Armazena o estado extrínseco do flyweight. Flyweight Define a interface através da qual os objetos flyweight recebem e agem em relação ao estado extrínseco. FlyweightFactory Cria e gerencia os objetos no pool de flyweight; Garante que o compartilhamento está correto.
Participantes do Padrão ConcreteFlyweight São compartilhadas. Implementa a interface flyweight e adiciona características intrínsecas. Ex.: Character. UnsharedConcreteFlyweight Não são compartilhadas; A interface permite o compartilhamento, mas não obriga a utilizá-lo; Ex.: Row, Column.
Colaborações Colaborações do Padrão Clientes devem obter Flyweights exclusivamente da Factory, sem instanciar o ConcreteFlyweight diretamente; O estado intrínseco é armazenado no ConcreteFlyweight; O estado extrínseco é armazenado no Client, que o passa ao Flyweight quando chamam suas operações.
Conseqüências Vantagens 1. Redução de consumo de memória como função de vários fatores: Redução do total de instâncias resultantes do compartilhamento; Quantidade de estado intrínseco armazenado por objeto; Se o estado extrínseco é armazenado ou computado. 2. Quanto mais objetos Flyweights, mais economia de memória. Desvantagens 1. Aumento do custos de run-time associados com transferência, busca e/ou computação do estado extrínseco. Compensado pela economia em uso de memória...
Código de Exemplo Considere o exemplo de motivação: um editor de textos. Definimos uma classe base para os objetos gráficos Flyweights (Gliph).
Código de Exemplo Sua subclasse Character é responsável apenas por armazenar o código do caractere.
Código de Exemplo A fim de armazenar os atributos extrínsecos usamos a classe GliphContext como um repositório de estados extrínsecos (fonte, por exemplo). Desse modo, qualquer operação que precise saber a fonte do glifo num contexto particular, receberá um objeto GliphContext como parâmetro.
Código de Exemplo Outro objeto necessário é o FlyweightFactory que cria glifos e garante que são compartilhados adequadamente. A classe GlyphFactory instancia Character e outros tipo de objetos glifos, compatilhando alguns (Character) e outros não (Row, Column).
Código de Exemplo O vetor character (pool) armazena ponteiros para glifos Character indexados pelo código do caracter. No construtor o vetor character é inicializado com zero.
Código de Exemplo A operação CreateCharacter busca a referência àquele caracter no vetor character (pool). Caso a referência exista, ela é retornada. adicionada ao vetor e retornada. Caso contrário, ela é criada,
Código de Exemplo As demais operações apenas instanciam um novo objeto quando ele é chamado, uma vez que eles não são compartilhados.
Padrões Relacionados Composite O padrão Flyweight é normalmente combinado com o padrão Composite; Esta combinação é usada para implementar a estrutura hierárquica lógica na forma de um grafo acíclico direcionado para o compartilhamento das folhas.
Obrigado pela atenção! Dúvidas?