originalmente publicado em http://50minutos.com.br/blog

Definição:

É um padrão que nos permite encapsular a instância de uma classe complexa usando uma instância de outra classe que possui a mesma interface. Com isso podemos controlar a criação e acesso aos objetos complexos usando objetos mais simples.

Quando usar:

  • Quando temos uma classe que possua dados sensíveis (que deveriam ser de acesso restrito);
  • Quando temos uma classe que acessa objetos remotos;
  • Quando temos uma classe em que a criação do objeto é muito demorada.
padrão proxy

Como usar:

  • Criar uma classe Proxy que implemente ISubject;
  • Adicionar um campo privado do tipo Subject;
  • Implementar ISubject (Request) de forma que ele chame o método correspondente (Request) da classe Subject (que NÃO herda de ISubject).

Exemplo 01:



using System;
using System.Threading;


namespace _50minutos_proxy
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Sem proxy\n---------\n");


            for (int i = 1; i <= 3; i++)
            {
                Usuario usuario = new Usuario();


                Console.WriteLine(usuario.Consultar());

                Console.WriteLine();
            }


            Console.WriteLine();
            Console.WriteLine();


            Console.WriteLine("Usando proxy para controlar a criação");
            Console.WriteLine("-------------------------------------");


            Console.WriteLine();


            IUsuario proxy;
            proxy = new ProxyUsuario();


            for (int i = 1; i <= 3; i++)
            {
                Console.WriteLine(proxy.Consultar());
                Console.WriteLine();
            }


            Console.ReadKey();
        }
    }


    //ISubject

    public interface IUsuario
    {
        //Request()
        String Consultar();
    }

    //Subject
    public class Usuario
    {
        public Usuario()
        {
            Console.WriteLine("criei");


            Thread.Sleep(2000);
        }


        //Request()
        public String Consultar()
        {
            return String.Format("consultei");
        }
    }


    //Proxy
    public class ProxyUsuario : IUsuario
    {
        //ISubject
        Usuario u;


        //Request
        public String Consultar()
        {
            if (this.u == null)
                this.u = new Usuario();


            return u.Consultar();
        }
    }
}


Exemplo 02:



using System;
using System.Threading;


namespace _50minutos_proxy
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Sem proxy\n---------\n");


            Usuario usuario = new Usuario();


            Console.WriteLine(usuario.Consultar());
            Console.WriteLine();


            Console.WriteLine();
            Console.WriteLine();


            Console.WriteLine("Usando proxy para controlar acesso");
            Console.WriteLine("----------------------------------");


            Console.WriteLine();


            ProxyUsuario proxy;
            proxy = new ProxyUsuario();


            //tentando consultar sem autenticar
            Console.WriteLine(proxy.Consultar());
            Console.WriteLine();


            //autenticando com senha incorreta
            Console.WriteLine(proxy.Autenticar("senhaErrada"));
            Console.WriteLine(proxy.Consultar());
            Console.WriteLine();


            //agora, sim...
            Console.WriteLine(proxy.Autenticar("53NH4"));
            Console.WriteLine(proxy.Consultar());
            Console.WriteLine();


            Console.ReadKey();
        }
    }


    //ISubject
    public interface IUsuario
    {
        //Request()
        String Consultar();
    }


    //Subject
    public class Usuario
    {
        public Usuario()
        {
            Console.WriteLine("criei");
        }


        //Request()
        public String Consultar()
        {
            return String.Format("consultei");
        }
    }


    //Proxy
    public class ProxyUsuario : IUsuario
    {
        //ISubject
        Usuario u;


        String senha = "53NH4";


        //Request
        public String Consultar()
        {
            String retorno = "autentique-se";


            if (this.u != null)
                retorno = u.Consultar();


            return retorno;
        }


        public String Autenticar(String s)
        {
            String retorno = "sem acesso";


            if (s == this.senha)
            {
                this.u = new Usuario();
                retorno = "usuário autenticado";
            }

            return retorno;
        }
    }
}