El patrón Proxy es uno de los patrones de diseño estructurales más utilizados en el desarrollo de software. Su principal propósito es controlar el acceso a un objeto mediante un intermediario o "proxy". Este patrón es especialmente útil cuando se desea agregar funcionalidad adicional a un objeto, como control de acceso, almacenamiento en caché, registro de eventos, entre otros, sin modificar el objeto original.
El patrón Proxy se utiliza para proporcionar un sustituto o marcador de posición para otro objeto. Un proxy puede controlar el acceso a ese objeto, realizar operaciones antes o después de que se acceda al objeto, o modificar el comportamiento del objeto.
El patrón Proxy se compone de tres elementos clave:
1. El sujeto real (Real Subject): El objeto original que se desea proteger o mejorar.
2. El proxy: Un intermediario que controla el acceso al sujeto real.
3. El cliente: La entidad que interactúa con el proxy en lugar de interactuar directamente con el sujeto real.
Implementar el patrón Proxy puede ofrecer varios beneficios, entre los cuales se incluyen:
El patrón Proxy se utiliza en diversas situaciones:
A continuación, se presenta una guía paso a paso para implementar el patrón Proxy en TypeScript.
Para empezar, asegúrate de tener Node.js y TypeScript instalados en tu máquina. Si no los tienes, puedes instalarlos utilizando los siguientes comandos:
npm install -g typescript
npm install -g ts-node
Crea un nuevo proyecto y configura TypeScript:
mkdir proxy-pattern
cd proxy-pattern
npm init -y
npm install typescript --save-dev
npx tsc --init
El primer paso es definir una interfaz común que será implementada tanto por el sujeto real como por el proxy. En este ejemplo, crearemos una interfaz Subject
con un método request
.
interface Subject {
request(): void;
}
Ahora, implementamos la clase que representa el sujeto real. Esta clase contiene la lógica principal que el proxy controlará.
class RealSubject implements Subject {
request(): void {
console.log('RealSubject: Handling request.');
}
}
La clase Proxy implementa la misma interfaz que el sujeto real. Este proxy controla el acceso al objeto real y puede añadir funcionalidades adicionales.
class ProxySubject implements Subject {
private realSubject: RealSubject;
constructor(realSubject: RealSubject) {
this.realSubject = realSubject;
}
request(): void {
if (this.checkAccess()) {
this.realSubject.request();
this.logAccess();
}
}
private checkAccess(): boolean {
console.log('ProxySubject: Checking access prior to firing a request.');
// Aquí podrías añadir lógica para verificar permisos, por ejemplo.
return true;
}
private logAccess(): void {
console.log('ProxySubject: Logging the time of request.');
// Aquí podrías registrar la operación en un sistema de logging.
}
}
Ahora que tenemos nuestra implementación lista, podemos utilizarla en nuestro código cliente. El cliente interactúa con el proxy como si estuviera interactuando con el sujeto real.
function clientCode(subject: Subject) {
subject.request();
}
console.log('Client: Executing the client code with a real subject:');
const realSubject = new RealSubject();
clientCode(realSubject);
console.log('');
console.log('Client: Executing the same client code with a proxy:');
const proxy = new ProxySubject(realSubject);
clientCode(proxy);
Para ejecutar el código, asegúrate de que todo esté correctamente compilado y ejecuta el siguiente comando en la terminal:
npx ts-node index.ts
Deberías ver una salida similar a la siguiente:
Client: Executing the client code with a real subject:
RealSubject: Handling request.
Client: Executing the same client code with a proxy:
ProxySubject: Checking access prior to firing a request.
RealSubject: Handling request.
ProxySubject: Logging the time of request.
El uso de TypeScript para implementar el patrón Proxy tiene varias ventajas:
El patrón Proxy es una herramienta poderosa en el desarrollo de software, que permite añadir capas de funcionalidad a un objeto sin modificar su código fuente. En TypeScript, la implementación de este patrón es bastante directa gracias a las características avanzadas del lenguaje, como el tipado estático y las interfaces.
Este patrón puede ser especialmente útil en aplicaciones grandes donde se necesite controlar el acceso a recursos críticos, mejorar el rendimiento mediante el almacenamiento en caché o incluso implementar políticas de seguridad. Al dominar el patrón Proxy en TypeScript, estarás mejor preparado para escribir código más robusto, mantenible y eficiente.
Si deseas profundizar más en patrones de diseño en TypeScript, te recomiendo explorar otros patrones estructurales como el patrón Decorator, Adapter y Facade, que también son muy útiles en el desarrollo de aplicaciones escalables y bien estructuradas.
Jorge García
Fullstack developer