Olha se alguém puder me explicar qual a verdadeira finalidade do Pattern Proxy eu agradeço, ja pesquisei e não encontrei nenhum o unico que vi não teve resposta.
nas pesquisas que realizei encontrei que o pattern proxy encapsula uma classe a qual ele faz referencia e deve utilizar-se da mesma interface de tal classe,
existe o proxy remoto, virtual proxy, mas preciso saber a necessidade de se utilizar o proxy?
Imagine que vc possui um objeto ou método que é altamente custoso ou complexo, e ainda, vc fará esta implementação em diferentes partes do seu código. Então o pattern proxy é recomendado para isto, em situações em que várias cópias que deve existir um objeto complexo, ele pode ser adaptado para incorporar o padrão de contrapeso, a fim de reduzir o consumo de memória da aplicação e consequentemente melhorar a performance e auxiliar na melhoria da manutenabilidade.
Ele funciona da seguinte forma:
Uma instância do objeto complexo é criado e são criados vários objetos proxy, pelos quais contêm uma única referência ao objeto original complexo e todas as interações com os objetos proxys são interadas ao objeto original complexo, uma vez que quando se utiliza os objetos proxys é liberada a memória do objeto complexo, uma vez que estes estão fora do escopo.
Não sei se fui claro o suficiente, mas creio que era esta explicação que vc queria, ok?
ViniGodoy
O proxy é uma classe que controla acesso à outra classe.
A
acidburn
Bem não sei se compreendi bem o que você disse, mas então que dizer que funciona assim exemplo:
Tenho uma classe que busca no banco uma imagem muito grande, então crio um proxy desta classe assim posso Instanciar o objeto real pela proxy somente quando necessário asim não alocando a memória antecipadamente
seria isso?
xjunior
acidburn:
Bem não sei se compreendi bem o que você disse, mas então que dizer que funciona assim exemplo:
Tenho uma classe que busca no banco uma imagem muito grande, então crio um proxy desta classe assim posso Instanciar o objeto real pela proxy somente quando necessário asim não alocando a memória antecipadamente
seria isso?
???
leia atentamente o que eu escrevi, se não entender, vou dar um exemplo mais simples, vc quer uma implementação para vc testar?
A
acidburn
O exemplo que estou tentando intender:
importjava.util.ArrayList;importjava.util.List;/** * Imagine que esta classe faz acessos ao banco de dados */classPessoaDAO{publicstaticPessoagetPessoaByID(Stringid){System.out.println("select * from PESSOA where id="+id);returnnewPessoaImpl(id,"Pessoa "+id);}}/** * Interface comum entre o objeto real e o Proxy */interfacePessoa{publicStringgetNome();publicStringgetId();}/** * Objeto real */classPessoaImplimplementsPessoa{privateStringnome;privateStringid;publicPessoaImpl(Stringid,Stringnome){this.id=id;this.nome=nome;// apenas para simular algo...System.out.println("Retornou a pessoa do banco de dados -> "+nome);}publicStringgetNome(){returnnome;}publicStringgetId(){returnthis.id;}}classProxyPessoaimplementsPessoa{privateStringid;privatePessoapessoa;//mesma interfacepublicProxyPessoa(Stringnome){this.id=nome;}/** * Método comum da interface * * @see Pessoa#getNome() */publicStringgetNome(){if(pessoa==null){//Apenas cria o objeto real quando chamar este métodopessoa=PessoaDAO.getPessoaByID(this.id);}/** Delega para o objeto real **/returnpessoa.getNome();}publicStringgetId(){returnthis.id;}}/** * Exemplo adaptado de "http://en.wikipedia.org/wiki/Proxy_pattern" */publicclassProxyExample{publicstaticvoidmain(String[]args){List<Pessoa>pessoas=newArrayList<Pessoa>();//Cria cada Proxy para encapsular o acesso a classe "PessoaImpl"pessoas.add(newProxyPessoa("A"));pessoas.add(newProxyPessoa("B"));pessoas.add(newProxyPessoa("C"));System.out.println("Nome: "+pessoas.get(0).getNome());// busca do banco de dadosSystem.out.println("Nome: "+pessoas.get(1).getNome());// busca do banco de dadosSystem.out.println("Nome: "+pessoas.get(0).getNome());// já buscou esta pessoa... apenas retorna do cache...// A terceira pessoa nunca será consultada no banco de dados (melhor performance - lazy loading)System.out.println("Id da 3ª - "+pessoas.get(2).getId());//pode imprimir o ID do objeto, e o proxy nao será inicializado.}}
exemplo tirado do DevMedia postado por Ricardo Rodrigues
A
acidburn
Segue explicação: do mesmo lugar referenciado a cima
Abaixo a saída do programa:
select * from PESSOA where id=A
Retornou a pessoa do banco de dados -> Pessoa A
Nome: Pessoa A
select * from PESSOA where id=B
Retornou a pessoa do banco de dados -> Pessoa B
Nome: Pessoa B
Nome: Pessoa A
Id da 3ª ? C
Conforme demonstrado no exemplo, uma consulta no banco de dados é realizada apenas quando o método ?getNome? da Pessoa é chamado. O Proxy controla este acesso, controlando a consulta para esta ser realizada apenas uma vez.
Note que o método ?pessoas.get(2).getId()? foi chamado para imprimir o ID da ?Pessoa C?, e isto não inicializou o proxy.
Þ Lembre-se: o importante é que o Proxy e o objeto real que está sendo encapsulado devem implementar a mesma interface.
Conclusão
O Pattern Proxy é muito utilizado em aplicações J2EE e por alguns frameworks, espero que tenham gostado deste breve artigo, e até a próxima.
xjunior
mano, favor editar seu post e colocar o código fonte dentro da tag “code”…
A
acidburn
Valeu pela dica, esta editado
P
pedro.lamarao
Um bom exemplo de aplicação de Proxy para funcionalidade, ao invés de economia, ocorre em frameworks de “remoting”.
Como uma referência direta à memória de outro processo é impossível, o programa local faz referência a um objeto Proxy ao invés; e o Proxy oculta a solução para o problema de comunicação entre processos.
Qualquer objeto que está para um sistema externo – como um conector de banco de dados – pode ser considerado um Proxy do sistema externo no programa local.
Note que “proxy” é inglês para “procurador” – uma pessoa legalmente habilitada a agir em nome de outra.
xjunior
então, de forma resumida::
Um proxy é um “passo” intermediário de um fluxo.
O proxy determina quando o objeto deve ser construído ou representado.
O Proxy serve para criar um substituto do objeto original.
Acho que entendi a sua concepção, vc disse sobre a imagem pois vc quer criar um objeto proxy para gerenciar a carga da imagem, aí sim está correto, o proxy pode te ajudar nisso…
Proxy remoto (Remote Proxy) - providencia um representante local de um objeto que se encontra num espaço de endereçamento diferente.
Proxy virtual (Virtual Proxy)- cria objetos dispendiosos apenas por pedido (on demand).
Proxy de proteção (Protection Proxy)- controla o acesso ao objeto original.
Qual tipo vc está querendo implementar?
A
acidburn
pedro.lamarao:
Um bom exemplo de aplicação de Proxy para funcionalidade, ao invés de economia, ocorre em frameworks de “remoting”.
Como uma referência direta à memória de outro processo é impossível, o programa local faz referência a um objeto Proxy ao invés; e o Proxy oculta a solução para o problema de comunicação entre processos.
Qualquer objeto que está para um sistema externo – como um conector de banco de dados – pode ser considerado um Proxy do sistema externo no programa local.
Note que “proxy” é inglês para “procurador” – uma pessoa legalmente habilitada a agir em nome de outra.
O que não consigo compreender é como você disse o Proxy é um procurador, porém nos exemplos que eu li, entendi que o proxy esta agindo como um intermediário em um determinado momento assim chamando uma classe para executar algo, como no exemplo a cima onde a classe proxy se não me engano é utilizada para realizar a consulta no banco me corrijam se estiver errado, mas qual a necessidade disso ?
xjunior
Na verdade, no seu exemplo o proxy é usado como um intermediário entre a consulta com o banco de dados, pois observe que na sua interface existe os métodos que devem ser implementados, e na sua classe ProxyPessoa implementa os métodos em comum com a classe PessoaImpl, realizando assim um proxy encapsula o PessoaImpl e vc usa na verdade o proxy.
Estude também os outros padrões estruturais, pois a filosofia deles são bem parecidas, e outros que são muito usados são pattern adpater e o decorator.
A
acidburn
xjunior:
Na verdade, no seu exemplo o proxy é usado como um intermediário entre a consulta com o banco de dados, pois observe que na sua interface existe os métodos que devem ser implementados, e na sua classe ProxyPessoa implementa os métodos em comum com a classe PessoaImpl, realizando assim um proxy encapsula o PessoaImpl e vc usa na verdade o proxy.
Estude também os outros padrões estruturais, pois a filosofia deles são bem parecidas, e outros que são muito usados são pattern adpater e o decorator.
mas xjunior o que não compreendo é o por que de usar isso, pois nunca implementei isso é um trabalho que estou fazendo então para realizar isso que esta acontecendo eu utilizo observer e oservable no mvc então o por que devo encapsular a classe PessoaImpl para realizar a consulta?
xjunior
Bom amigo, lembre-se que o observer é um padrão comportamental e não estrutural, visite este link que irá dar uma visão semântica sobre os design patterns e como utilizá-los, não tem implementação, mas é excelente fonte para vc saber o que é e como implementar.
O objetivo na lata do proxy é transformar algo complexo em simples e lembra do proxy em servidor, para que ele serve???
Este design pattern nao possui filosofia diferente, e sim um proxy na empresa (lembrando do servidor…) guarda cache das páginas acessadas, não é? Implementa segurança, e faz com que o acesso seja “mais rápido”…
O design pattern proxy é para fazer o acesso ser mais rápido em algo custoso… Ter um intermediário entre o complexo e a sua implementação, ok?
ViniGodoy
acidburn:
Tenho uma classe que busca no banco uma imagem muito grande, então crio um proxy desta classe assim posso Instanciar o objeto real pela proxy somente quando necessário asim não alocando a memória antecipadamente
seria isso?
É exatamente isso. Um proxy pode controlar acesso por diversos motivos:
Lazy loading (exemplo que você deu);
Controle ou restrições de acesso;
Sincronização
Caching (exemplo dado pelo xjunior);
O proxy não adiciona nenhuma funcionalidade aparente a quem usa a classe. É diferente do decorator, que agrega uma função. Diferenciar um do outro as vezes é bastante difícil.
As collections do Java fornecem dois tipos de proxy. Um deles para tornar a collection read-only e outro para fornecer acesso sincronizado.
List<String> lista = new ArrayList<String>();
List<String> listaSincronizada = Collections.synchronizedList(lista);
List<String> listaReadOnly = Collections.unmodifiableList(lista);
Não confundir esse proxy com o proxy dinâmico do Java, a classe Proxy.
A
acidburn
xjunior:
Bom amigo, lembre-se que o observer é um padrão comportamental e não estrutural, visite este link que irá dar uma visão semântica sobre os design patterns e como utilizá-los, não tem implementação, mas é excelente fonte para vc saber o que é e como implementar.
não consigo acessar o proxy esta com erro no link que você sugeriu
ViniGodoy
Ah, outro detalhe. Não confudir:
O design pattern com a classe Proxy;
O design pattern com um servidor de Proxy;
O proxy também se comporta como a classe que você quer acessar. O usuário pode nem saber que está lidando com um proxy. Note no exemplo acima, que nos 3 casos você acaba com um List<String> na mão. No caso da sua classe de imagem, o proxy e a imagem deveriam implementar uma interface comum, Image.
A classe ficaria assim:
//Interface comumpublicinterfaceImage{voiddraw(Graphics2Dg);}//Sua classe de negóciopublicclassMyImageextendsImage{privateBufferedImageimage;publicMyImage(BufferedImageimg){image=img;}publicvoiddraw(Graphics2Dg){g.drawImage(image,0,0,null);}}//ProxypublicclassLazyImageProxyimplementsImage{privateMyImageimage=null;privateFilefile;publicLazyImageProxy(Filefile){this.file=file;}privateImagelazyImage(){if(image==null)image=newMyImage(ImageIO.read(newFile("C:/ImagemGrandeEPesada.tiff")));returnimage;}publicvoiddraw(Graphics2Dg){lazyImage.draw(g);}}
Note que alguns poderiam argumentar que aquele proxy é, na verdade, um decorator, já que ele acrescenta a funcionalidade de lazy-loading. Isso é restrição de acesso ou funcionalidade extra? Depende do ponto de vista… em todo caso a implementação seria idêntica e, na minha opinião, discutir isso é discutir o sexo dos anjos.
A
acidburn
Por qual motivo a terceira pessoa não sera chamada, vejo que o modelo que esta sendo utilizado esta diferente é por isso?
System.out.println("Nome: " + pessoas.get(0).getNome()); // busca do banco de dados
System.out.println("Nome: " + pessoas.get(1).getNome()); // busca do banco de dados
System.out.println("Nome: " + pessoas.get(0).getNome()); // já buscou esta pessoa... apenas
System.out.println("Id da 3ª - " + pessoas.get(2).getId());//pode imprimir o ID do objeto, e o proxy nao será inicializado.
P
pedro.lamarao
acidburn:
pedro.lamarao:
Um bom exemplo de aplicação de Proxy para funcionalidade, ao invés de economia, ocorre em frameworks de “remoting”.
Como uma referência direta à memória de outro processo é impossível, o programa local faz referência a um objeto Proxy ao invés; e o Proxy oculta a solução para o problema de comunicação entre processos.
Qualquer objeto que está para um sistema externo – como um conector de banco de dados – pode ser considerado um Proxy do sistema externo no programa local.
Note que “proxy” é inglês para “procurador” – uma pessoa legalmente habilitada a agir em nome de outra.
O que não consigo compreender é como você disse o Proxy é um procurador, porém nos exemplos que eu li, entendi que o proxy esta agindo como um intermediário em um determinado momento assim chamando uma classe para executar algo, como no exemplo a cima onde a classe proxy se não me engano é utilizada para realizar a consulta no banco me corrijam se estiver errado, mas qual a necessidade disso ?
Talvez a questão não seja sobre necessidade, mas sobre utilidade.
É claro que um idéia de um Proxy puro parece inútil – se ele é idêntico ao objeto original, porque não acessar o objeto original logo de uma vez?
O Proxy parece mais útil quando ele oculta alguma regra adicional que seja útil.
No seu exemplo, essa regra adicional parece ser um cache de dados recuperados do banco – de modo que os acessos subsequentes são mais econômicos.
ViniGodoy
No proxy que você implementou, é pq o método getId() não aciona a busca. Como o id é passado no construtor e o proxy o armazena internamente, não tem pq fazer busca se você só quiser saber o id. Se fizer pessoa.get(2).getNome() aí sim, a busca será acionada.
A
acidburn
No proxy que você implementou, é pq o método getId() não aciona a busca. Como o id é passado no construtor e o proxy o armazena internamente, não tem pq fazer busca se você só quiser saber o id. Se fizer pessoa.get(2).getNome() aí sim, a busca será acionada.
a então é isso mesmo
A
acidburn
System.out.println("Nome: " + pessoas.get(0).getNome()); // busca do banco de dados
System.out.println("Nome: " + pessoas.get(1).getNome()); // busca do banco de dados
System.out.println("Nome: " + pessoas.get(0).getNome()); // já buscou esta pessoa... apenas
System.out.println("Id da 3ª - " + pessoas.get(2).getId());//pode imprimir o ID do objeto, e o proxy nao será inicializado.
Por que na busca da segunda pessoa ele alega estar no cache, é por que o objeto proxy vai estar carregado com dados?
ViniGodoy
Sim. E num segundo getNome() ele não buscará nada no banco.
xjunior
Isto mesmo, acidbun, então ele não buscará pois fará o cache desta busca…