CorEngine

Creando un engine para el desarrollo de software y videojuegos

Design Patterns: El patrón intermediario (Proxy), controlar el acceso a un objeto

Publicado por FX Programmer en 19 Mayo 2009

El proxy es un intermediario (que también implementa el interfase del objeto real) y que nos permite añadir o modificar comportamiento sin reescribir el objeto real. En escribir() del proxy añado el número de línea y delega en la Pizarra el resto de comportamiento. Es interesante observar que este patrón evita abusar del uso de herencia. Este abuso es la primera tentación del novato, ya que piensa: “si quiero modificar el comportamiento de una clase hago el nuevo comportamiento en una clase hija”. No es que la herencia sea de partida ilegal o inconveniente, simplemente se trata de no abusar de ella aplicándola a todo tipo de problema. De esta forma no caeremos en el vicio de aquel que sólo sabía usar martillos y todos los problemas le parecían clavos.

Se lo suele emplear para ocultar un objeto (denominado Objeto Real) del cliente, haciendo que un segundo objeto (El Proxy) ofrezca la misma interfaz de éste (el Objeto Real). El objeto que actúa de Proxy redirije, redirecciona, o invoca a los métodos del Objeto Real cuando sea necesario. Quien tiene el control real sobre los verdaderos objetos es el Proxy. Es decir que el Proxy se encarga de comunicarse y tomar las decisiones adecuadas para responder a las necesidades del cliente.

Con esto se consigue hacer que el Cliente piense que actúa con el Objeto Real, pero en realidad es el Proxy con quien se comunica. Es este Proxy quien actúa de intermediario entre el Cliente y el Objeto Real (o dicho en forma general: con los Objetos reales) y decide como llevar a cabo dicha comunicación.

Es un patrón muy útil cuando se desea evitar o proteger el acceso a uno o varios objetos cuando la lógica o complejidad de las operaciones de los objetos reales varían.

Es el Proxy quien le oculta la complejidad al Cliente.

proxy

El patrón obliga que las llamadas a un objeto ocurran indirectamente a través de un objeto proxy, que actúa como un sustituto del objeto original, delegando luego las llamadas a los métodos de los objetos respectivos.

El cliente no necesita saber que no está accediendo al objeto real(Subject) directamente.  En otras palabras, el proxy substituye al objeto real.  En C++ esto podría significar que ambos, el proxy y la clase sujeto tienen una clase común de base. Como tal, la clase Proxy es sólo un envolvente trivial para cualquier objeto. Sin embargo, su función principal es la de servir a su clase base para implementaciones más específicas.

Por ejemplo, tenemos una clase que contiene un método llamado __gettattr__ que sólo es llamado como el último recurso el proxy puede manejar un método sujeto diferentemente “sobrecargándolo” en la clase proxy.

Otro ejemplo, accedemos una instancia de la clase RGB primero directamente, luego utilizando una instancia de Proxy genérica como una envolvente y finalmente a través de una instancia de NoBlueProxy.

Participantes

  • Subject: Interfaz o clase abstracta que proporciona un acceso común al objeto real y su representante (proxy).
  • Proxy: Mantiene una referencia al objeto real. Controla la creación y acceso a las operaciones del objeto real.
  • RealSubject: Define el objeto real representado por el Proxy.

proxy2

Implementación

Tenemos un objeto padre Asunto del que heredan otros dos:AsuntoReal y Proxy, todos ellos tienen un método petición(). El cliente llamaría al método petición() de Asunto, el cual pasaría la petición a Proxy, que a su vez instanciaría AsuntoReal y llamaría a su petición().

Esto nos permite controlar las peticiones a AsuntoReal mediante el Proxy, por ejemplo instanciando AsuntoReal cuando sea necesario y eliminándolo cuando deje de serlo.

En la practica:

Quiero salvar una lista de usuarios registrados, pero no sé exactamente donde. La cuestión es que dependiendo del valor de un checkbox ( en el que el usuario elige si está conectado a internet o no ), debo mandar los datos a servidor ( en formato XML ) o guardarlos en disco en un Shared Object

Esta es una misión para el patrón Proxy. ¿Por qué?. Porque quiero aislar el proceso de guardar los datos del resto del programa, simplemente quiero decir, “eh, guárdame esto” y olvidarme de cómo o dónde se guarda.

Eso es lo que hace este patrón. El proxy guarda una referencia a un objeto, que es quien realmente se encargará de ejecutar la acción. Pero es el proxy el que crea ese objeto, por lo que puede crear una instancia de una u otra clase dependiendo de ciertas condiciones en tiempo de ejecución

Por tanto, todas las clases que puedan ser instanciadas por el proxy, deben implementar el mismo interfaz. Y dependiendo del tipo de proxy, puede ser una buena idea que incluso él mismo implemente ese interfaz, para que se pueda eliminar si es necesario.

Sistemas:

Un servidor proxy es un equipo intermediario situado entre el sistema del usuario e Internet. Puede utilizarse para registrar el uso de Internet y también para bloquear el acceso a una sede Web.

El servidor de seguridad del servidor proxy bloquea algunas redes o páginas Web por diversas razones. En consecuencia, es posible que no pueda descargar el entorno de ejecución de Java (JRE) o ejecutar algunos applets de Java.

Servidores proxy: Funcionan como servidor de seguridad y como filtro de contenidos. Son un mecanismo de seguridad implementado por el ISP o los administradores de la red en un entorno de Intranet para desactivar el acceso o filtrar las solicitudes de contenido para ciertas sedes Web consideradas ofensivas o dañinas para la red y los usuarios. Mejoran el rendimiento. Guardan en la memoria caché las páginas Web a las que acceden los sistemas de la red durante un cierto tiempo. Cuando un sistema solicita la misma página web, el servidor proxy utiliza la información guardada en la memoria caché en lugar de recuperarla del proveedor de contenidos. De esta forma, se accede con más rapidez a las páginas Web.

Ejemplo

//: C10:ProxyDemo.cpp
// Simple demonstration of the Proxy pattern.
#include <iostream>

using namespace std;

class ProxyBase
{

public:

virtual void f() = 0;
virtual void g() = 0;
virtual void h() = 0;
virtual ~ProxyBase() {}

};

class Implementation : public ProxyBase
{

public:

void f() { cout << “Implementation.f()” << endl; }
void g() { cout << “Implementation.g()” << endl; }
void h() { cout << “Implementation.h()” << endl; }

};

class Proxy : public ProxyBase
{

ProxyBase* implementation;

public:

Proxy() { implementation = new Implementation(); }
~Proxy() { delete implementation; }

// Forward calls to the implementation:
void f() { implementation -> f(); }
void g() { implementation -> g(); }
void h() { implementation -> h(); }

};

int main()
{

Proxy p;
p.f();
p.g();
p.h();

}

Escribe un comentario

XHTML: Puedes usar estas etiquetas: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>