Para um bom resultado do uso deste padrão,use-o quando todas as afirmativas seguintes forem verdadeiras:
- A aplicação usa um grande número de objetos;
- Custos de armazenamento são grandes por causa da grande quantidade de objetos;
- A maior parte do estado dos objetos podem ser extrínseco (informações que dependem e variam com o contexto do flyweight, e que por esse motivo nao podem ser compartilhados);
- Muitos grupos de objetos podem ser substituídos por poucos objetos que possam ser compartilhados (estado extrínseco deve ser removido para outro lugar);
- A aplicação não depende da identidade do objeto;
Ainda deve-se pensar sobre o ponto fraco do padrão, que é dependendo da quantidade e da organização dos objetos a serem compartilhados, pode haver um grande custo para procura deles. Então ao utilizar o padrão deve ser analisado qual a prioridade no projeto, espaço ou tempo de execução.
Os participantes deste padrão seriam:
- Cliente : computa ou armazena o estado extrínseco do flyweight, assim como mantém a referência para ele;
- Flyweight: declara uma interface por onde pode receber e atuar sobre estados extrínsecos;
- FlyweightFactory: cria e gerencia objetos flyweights e garante que eles sejam compartilhados corretamente. Quando um cliente solicita um flyweight, um objeto FlyweightFactory fornece a ele, ou cria se caso ele não exista.
- ConcretesFlyweights (no exemplo do processador de texto seria o caractere em si): implementa a interface Flyweight e armazena só os estados intrísecos (compartilháveis).
Um bom exemplo da utilização é no desenvolvimento de jogos, afinal são usadas várias imagens que representam as entidades que compõe o jogo (cenário, jogador, inimigo..).
Isso causa duplicação de informação.Por exemplo, quando aparecem vários inimigos iguais no jogo, o mesmo conjunto de imagens é criado repeditas vezes.
Para exemplificar isso em código, começamos criando uma classe Imagem (informação intríseco):
public class Imagem { protected String NomedaImagem; public Imagem(String imagem) { NomedaImagem = imagem; } public void desenharImagem() { System.out.println(NomedaImagem + " desenhada!"); } }
Entao criar a classe Ponto (informação extrínseco):
public class Ponto { public int x, y; public Ponto(int x, int y) { this.x = x; this.y = y; } }Uma classe Flyweight será feita para armazenar o método de desenho da imagem em um determinado ponto:
public abstract class SpriteFlyweight { public abstract void desenharImagem(Ponto ponto); }Após a criação da classe Flyweight, criamos uma classe Flyweight Concreta, que seria a implementação da operação de fato:
public class Sprite extends SpriteFlyweight { protected Imagem imagem; public Sprite(String nomeDaImagem) { imagem = new Imagem(nomeDaImagem); } @Override public void desenharImagem(Ponto ponto) { imagem.desenharImagem(); System.out.println("No ponto (" + ponto.x + "," + ponto.y + ")!"); } }A classe fábrica guardará todas as imagens que serão compartilhadas e terá um método para pega-las, tendo assim todo acesso as imagens centralizado nessa classe:
public class FlyweightFactory { protected ArrayListE utilizando esse padrão:flyweights; public enum Sprites { JOGADOR, INIMIGO_1, INIMIGO_2, CENARIO_1 } public FlyweightFactory() { flyweights = new ArrayList(); flyweights.add(new Sprite("jogador.png")); flyweights.add(new Sprite("inimigo1.png")); flyweights.add(new Sprite("inimigo2.png")); flyweights.add(new Sprite("cenario1.png")); } public SpriteFlyweight getFlyweight(Sprites jogador) { switch (jogador) { case JOGADOR: return flyweights.get(0); case INIMIGO_1: return flyweights.get(1); case INIMIGO_2: return flyweights.get(2); default: return flyweights.get(3); } } }
public static void main(String[] args) { FlyweightFactory factory = new FlyweightFactory(); factory.getFlyweight(Sprites.JOGADOR).desenharImagem(new Ponto(10, 10)); factory.getFlyweight(Sprites.INIMIGO_1).desenharImagem( new Ponto(100, 10)); factory.getFlyweight(Sprites.INIMIGO_1).desenharImagem( new Ponto(120, 10)); factory.getFlyweight(Sprites.INIMIGO_1).desenharImagem( new Ponto(140, 10)); factory.getFlyweight(Sprites.INIMIGO_2).desenharImagem( new Ponto(60, 10)); factory.getFlyweight(Sprites.INIMIGO_2).desenharImagem( new Ponto(50, 10)); }Pode ser implementado algo para eliminar um objeto nao usado mais, liberando ele da memória e diminuindo espaço.
Referências :
Livro - Padroes de Projetos - Solucoes Reutilizaveis - Gamma Erich
Site - http://brizeno.wordpress.com/category/padroes-de-projeto/flyweight/
Nenhum comentário:
Postar um comentário