Proxy

Intenção

Fornece um substituto de outro objeto para controlar o acesso a esse objeto. 

Vantagens

Desvantagens

Exemplos

Exemplo #1

A aplicação web de um museu contém páginas com um grande número de imagens. Como o carregamento dessas imagens é muito custoso, deseja-se implementar um recurso que permita que cada imagem seja carregada em uma página apenas quando for acessada pelo usuário da aplicação.

Uma interface Image é definida com a operação show(). Sempre que o usuário acessar uma página, os nomes das imagens serão exibidos pelo método showName() da classe ProxyImage. Caso o usuário selecione um dos nomes listados, o método show() de ProxyImage delegará a exibição da imagem real para o método show() de RealImage fazendo com que a imagem seja carregada na página. A classe ProxyImage é uma classe substituta da classe RealImage, que só é instanciada quando o usuário acessa o nome de uma imagem específica.

Diagrama de Classe

Exemplo #1 - Diagrama

Participantes

Proxy (ProxyImage): Mantém uma referência que permite ao proxy acessar o objeto real.

Subject (Image): Define uma interface comum de forma que o proxy possa ser utilizado em qualquer lugar em que um RealSubject é esperado.

RealSubject (RealImage): Define o objeto real que o proxy representa.

Código

package br.padroes.ImageProxy;

public class Client {

	
	public static void main(String[] args) {
	int clicked;	
		
        System.out.println("List or folder of images displayed!");  
	Image image1 = new ProxyImage("serverfolder/monalisa.jpeg","Mona lisa");
              image1.showName(); //displays only the name of the image
	Image image2 = new ProxyImage("serverfolder/lastsupper.jpeg","The Last Supper");
	      image2.showName();
        
        clicked = 1; //For example, user clicked on the image 1!
        switch(clicked){
            case 1 -> image1.show();   //  assuming that the click was made on image 1.
            case 2 -> image2.show();   //  assuming that the click was made on image 2.
            //case 3 -> Image3.showImage("serverfolder/image3.jpeg","Imagem 3");   //  assuming that the click was made on image 3.
       }
   }
		
}
package br.padroes.ImageProxy;

public interface Image {
    
    public void show();
    public void showName();
    
}

package br.padroes.ImageProxy;

/**
 * Proxy
 */
public class ProxyImage implements Image {

	private String imagePath;
        private String imageName;
        private RealImage image;
    	
	public ProxyImage(String imagePath, String imageName) {
	     this.imagePath=imagePath; 
             this.imageName=imageName;
	}
       
        public RealImage getImage(){
            
            image = new RealImage(imagePath,imageName);
            
        return image;    
            
        }
	
	@Override
	public void show() {

		System.out.println("User clicked on the image! ");             
	        System.out.println(" loadinnng...!");          
		this.getImage().show(); //Chama show() de RealImage.		
	}
        
        @Override
         public void showName(){ // será chamado antes do click
            System.out.println("Image Name:  "+imageName);   
            
        }

}
package br.padroes.ImageProxy;

public class RealImage implements Image {

    private String imagePath;
    private String imageName;
    
   public RealImage(String imagePath, String imageName) {
        this.imagePath=imagePath; 
        this.imageName=imageName;
       //this.loadImage(this.imagePath, this.imageName);                 
	}
 
   @Override
   public void show() {
        System.out.println("Real Image: "+imageName+ " LOADED!"+ " in :" + imagePath);   
    }
    
    @Override
         public void showName(){
            System.out.println("Image Name:  "+imageName);   
            
        }
  
   

}
Clique aqui para fazer o download do código completo de implementação deste Design Pattern.

Padrões Relacionados

Este Padrão pode ser usado para resolver os seguintes problemas: