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.
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;
}
}
}