Proxy (patrón de diseño)

El patrón Proxy es un patrón estructural que tiene como propósito proporcionar un subrogado o intermediario de un objeto para controlar su acceso.

Patrón Proxy

Un proxy, en su forma más general, es una clase que funciona como una interfaz para otra cosa. El proxy podría interactuar con cualquier cosa: una conexión de red, un objeto grande en la memoria, un archivo o algún otro recurso que sea costoso o imposible de duplicar. En resumen, un proxy es un contenedor o un objeto de agente que el cliente está llamando para acceder al objeto de servicio real detrás de escena. El uso del proxy puede ser simplemente reenvío al objeto real, o puede proporcionar lógica adicional. En el proxy, se puede proporcionar una funcionalidad adicional, por ejemplo, el almacenamiento en caché cuando las operaciones en el objeto real requieren muchos recursos, o la comprobación de las condiciones previas antes de que se invoquen las operaciones en el objeto real. Para el cliente, el uso de un objeto proxy es similar al uso del objeto real, porque ambos implementan la misma interfaz.[1]

Motivación

Para explicar la motivación del uso de este patrón veamos un escenario donde su aplicación sería la solución más adecuada al problema planteado. Consideremos un editor que puede incluir objetos gráficos dentro de un documento. Se requiere que la apertura de un documento sea rápida, mientras que la creación de algunos objetos (imágenes de gran tamaño) es costosa. En este caso no es necesario crear todos los objetos con imágenes nada más abrir el documento porque no todos los objetos son visibles. Interesa por tanto retrasar el coste de crear e inicializar un objeto hasta que es realmente necesario (por ejemplo, no abrir las imágenes de un documento hasta que no son visibles). La solución que se plantea para ello es la de cargar las imágenes bajo demanda. Pero, ¿cómo cargar las imágenes bajo demanda sin complicar el resto del editor? La respuesta es utilizar un objeto proxy. Dicho objeto se comporta como una imagen normal y es el responsable de cargar la imagen bajo demanda.

Aplicabilidad

El patrón proxy se usa cuando se necesita una referencia a un objeto más flexible o sofisticada que un puntero. Dependiendo de la función que se desea realizar con dicha referencia podemos distinguir diferentes tipos de proxies:

  • proxy remoto: representante local de un objeto remoto.
  • proxy virtual: crea objetos costosos bajo demanda (como la clase ImagenProxy en el ejemplo de motivación).
  • proxy de protección: controla el acceso al objeto original (ejemplo de proxy de protección: [1])
  • proxy de referencia inteligente: sustituto de un puntero que lleva a cabo operaciones adicionales cuando se accede a un objeto (ej. contar número de referencias al objeto real, cargar un objeto persistente bajo demanda en memoria, control de concurrencia de acceso tal como bloquear el objeto para impedir acceso concurrente, …).

Participantes

La clase Proxy : mantiene una referencia al objeto real (en el siguiente ejemplo se le denomina _sujetoReal) y proporciona una interfaz idéntica al sujeto (la clase Sujeto). Además controla el acceso a dicho objeto real y puede ser el responsable de su creación y borrado. También tiene otras responsabilidades que dependen del tipo de proxy:

  • proxy remoto: responsable de codificar una petición y sus argumentos, y de enviarla al objeto remoto.
  • proxy virtual: puede hacer caché de información del objeto real para diferir en lo posible el acceso a este.
  • proxy de protección: comprueba que el cliente tiene los permisos necesarios para realizar la petición.


La clase Sujeto: define una interfaz común para el proxy (Proxy) y el objeto real (de la clase SujetoReal), de tal modo que se puedan usar de manera indistinta.

La clase SujetoReal: clase del objeto real que el proxy representa.

Colaboraciones

Dependiendo de la clase de proxy, el objeto proxy redirige las peticiones al objeto real que representa.

Ejemplos de funcionamiento:

  • Diagrama de clases para un ejemplo del patrón proxy.[2]
  • Diagrama de secuencia para un ejemplo en el que no se utiliza el patrón proxy. [3]
  • Diagrama de secuencia para un ejemplo en el que se utiliza el patrón proxy.[4]

Consecuencias

El uso de un proxy introduce un nivel de indirección adicional con diferentes usos:

  • Un proxy remoto oculta el hecho de que un objeto reside en otro espacio de direcciones.
  • Un proxy virtual puede realizar optimizaciones, como la creación de objetos bajo demanda.
  • El proxy de protección y las referencias inteligentes permiten realizar diversas tareas de mantenimiento adicionales al acceder a un objeto.

Además, su uso también permite realizar una optimización COW (copy-on-write) , puesto que copiar un objeto grande puede ser costoso, y si la copia no se modifica, no es necesario incurrir en dicho gasto. Además el sujeto mantiene un número de referencias, y solo cuando se realiza una operación que modifica el objeto, este se copia. Es útil por tanto para retrasar la replicación de un objeto hasta que cambia.

Implementación

Ejemplo Java

/**
 * Clase Cliente:  el cliente del sujeto tan solo conoce que maneja un objeto de la
 * clase Sujeto. Por tanto, funciona indistintamente con el SujetoReal
 * como con su Proxy.
 */

public class Cliente {

  /**
  * El constructor guarda la referencia al sujeto.
  */

  public Cliente(Sujeto sujeto) {
       _sujeto = sujeto; 
  }
 /** 
   * Lo único que realiza el cliente en su método ejecutar es 
   * llamar 2 veces al metodo1, luego 1 vez al metodo2, 
   * y de nuevo al metodo1. _sujeto, ejecutará el método dependiendo
   * si fue creado como proxy o sujetoReal.
   */

  public void ejecutar() {
        _sujeto.metodo1();
        _sujeto.metodo1();
        _sujeto.metodo2();
        _sujeto.metodo1();
  }

 /**
   *  La clase Cliente tiene el atributo _sujeto que le permite tener una referencia al sujeto al que 
   *  el cliente envía la petición de ejecutar un determinado método.
   */ 

     private Sujeto _sujeto;
      
 }
/**
   * La clase Sujeto dentro del patrón Proxy es la interfaz del sujeto
   * real de cara al exterior (Cliente). Es una clase abstracta cuyos
   * métodos serán implementados tanto por el sujeto real como por el proxy.
   */

   public abstract class Sujeto {

  /**
    * El constructor guarda el nombre del sujeto.
    */
     public Sujeto(String nombre) { 
         _nombre = nombre; 
    }
           
  /**
   * Método que devuelve el nombre del sujeto.
   */
     public String toString() { 
          return _nombre; 
    }

  /**
   * Métodos definidos de forma abstracta en la clase Sujeto, y que tendrán distintas implementaciones en las clases que heredan de ésta: Proxy
   * y SujetoReal.
   */

     public abstract void metodo1();
     public abstract void metodo2();

  /**
   * Este método llama al método toString() de la clase Proxy. Se le pasa un objeto de la clase Sujeto, pero se considera que se trata de un objeto proxy.
   */

     public void status (Sujeto sujeto) {
         Proxy p;
         p = (Proxy) sujeto;
         p.toString();
     }   
                       
  /**
   *  La clase Sujeto tiene el atributo _nombre , que indica el nombre  de un sujeto,  tanto si se trata de un proxy
   *  como de un sujeto real.
   */ 

     private String  _nombre;

}
/**
 * Éste es el objeto Proxy. Este proxy es simultáneamente un 
 *
 * (a) proxy virtual que retrasa la creación del objeto real hasta que
 *     se invoca alguno de sus métodos.
 * (b) referencia inteligente, realizando labores de contabilización
 *     del número de veces que se invoca un método.
 */

public class Proxy extends Sujeto {

   /**
    * el constructor de la clase, además de inicializar a la parte
    * correspondiente a la superclase, establece a null la referencia
    * al sujeto real e inicializa la contabilización.
    */

  public Proxy (String nombre) {
     super(nombre);
    _sujetoReal = null;
   _accesosMetodo1 = 0;
   _accesosMetodo2 = 0;
  }

  /**
   * En lugar de realizar de cada vez una comprobación de si el
   * sujeto real esta creado y en caso contrario crearlo, se define
   * este método privado.
   */

  private SujetoReal obtenerSujetoReal() {
    if (_sujetoReal == null)
      _sujetoReal = new SujetoReal(this + " (Real)");

    return _sujetoReal;
  }
 /**
   * Los métodos delegan en el sujeto real.
   */

  public void metodo1() { 
    _accesosMetodo1++; 
    obtenerSujetoReal().metodo1(); 
  }

  public void metodo2() { 
    _accesosMetodo2++;
    obtenerSujetoReal().metodo2(); 
  }

  /**
    * Este método permite presentar información de contabilización
    * de uso del objeto.
    */

  public String toString() {
    if (_sujetoReal != null)
      System.out.println("Accesos a " + _sujetoReal + 
                         ": metodo1=" + _accesosMetodo1 + 
                         ", metodo2=" + _accesosMetodo2);
    else 
      System.out.println("Sujeto Real (" + this + ") no creado.");

    return "";
  }

  /**
   * Atributos privados: _sujetoReal que le permite a la clase Proxy tener una referencia al sujeto real y los contabilizadores de los accesos a
  * los métodos 1 y 2.
   */

  private SujetoReal _sujetoReal; 
  private int  _accesosMetodo1, _accesosMetodo2;
}
/** 
 * La clase SujetoReal es el objeto sobre el que queremos
 * implementar un proxy. Extiende la clase Sujeto implementando los
 * métodos del sujeto (en realidad es el sujeto el que presenta
 * la interfaz de los métodos del sujeto real...)
 */

public class SujetoReal extends Sujeto {

  public SujetoReal(String nombre) { 
     super(nombre); 
     // aquí aparece el código de una inicialización costosa: por ejemplo,  añadir un objeto (que se le pasase como parámetro al constructor) a
     // un vector que tuviese como atributo esta misma clase (SujetoReal), y luego ordenar dicho vector de 
     // mayor a menor en función de un atributo entero que tuviese la clase a la que pertenecen los objetos que contiene el vector.
     // Otro ejemplo de inicialización costosa sería el llamar en el constructor a un método de esta clase: por
     //  ejemplo loadImageFromDisk() lo cual sería lógico si  se tratase de una clase ImagenReal que tuviese como proxy la clase ProxyReal y 
     // como clase abstracta de la que hereda, la clase Imagen.
  }

  public void metodo1()  {
      System.out.println("Ejecutando metodo1 en " + this);
   }

  public void metodo2() {
      System.out.println("Ejecutando metodo2 en " + this);
   }

}
public class Main {

   public static void main(String argv[]) {

    Sujeto objetoA = new Proxy("objetoA");
    Cliente c = new Cliente(objetoA);
    objetoA.status(objetoA);
    c.ejecutar();
    objetoA.status(objetoA);

  
    Sujeto objetoB = new SujetoReal("objetoB");
    Cliente d = new Cliente(objetoB);
    
    d.ejecutar();
  }

}

Patrones relacionados

  • El patrón Adaptador proporciona una interfaz diferente al objeto que adapta, mientras que el proxy tiene la misma interfaz, pero ambos redirigen la petición del cliente al verdadero sujeto que la ejecuta con la posibilidad de incorporar lógica adicional : comprobación de acceso, creación del sujeto real…
  • El Proxy se puede diseñar de manera similar al patrón decorador, pero el propósito es diferente: el decorador añade responsabilidades a un objeto, el proxy solo controla su acceso. Así, si el proxy no tiene una fuerte dependencia con el sujeto real (por ejemplo, no es de creación), y no tiene que instanciarlo, puede adoptar el mismo diseño que el decorador, y ser un proxy de cualquier sujeto (referencia a la interfaz que el cliente conoce).

Ejemplos comunes de la aplicación del patrón proxy

A continuación se presentan algunos de los ejemplos más comunes en los que se utiliza el patrón proxy :

  • Añadir acceso de seguridad a un objeto existente. El proxy determinará si el cliente puede acceder al objeto de interés (proxy de protección).
  • Proporcionando interfaz de recursos remotos como el servicio web o recursos REST.
  • Coordinación de las operaciones costosas en recursos remotos pidiendo los recursos a distancia para iniciar la operación tan pronto como sea posible antes de acceder a los recursos.
  • Agregar una operación segura para los subprocesos a una clase existente sin cambiar el código de la clase existente.

Enlaces externos

Read other articles:

Artikel ini sebatang kara, artinya tidak ada artikel lain yang memiliki pranala balik ke halaman ini.Bantulah menambah pranala ke artikel ini dari artikel yang berhubungan atau coba peralatan pencari pranala.Tag ini diberikan pada Februari 2023. Dendragama schneideri TaksonomiKerajaanAnimaliaFilumChordataKelasReptiliaOrdoSquamataFamiliAgamidaeGenusDendragamaSpesiesDendragama schneideri Ahl, 1926 lbs Dendragama schneideri, atau agama pohon Schneider, adalah sebuah spesies kadal dalam keluarga ...

 

Comics character Andrew BennettCover of The House of Mystery #290 (March 1981), art by Joe Kubert.Publication informationPublisherDC ComicsFirst appearanceThe House of Mystery #290 (March, 1981)Created byJ. M. DeMatteis (writer)Tom Sutton (artist)In-story informationFull nameAndrew BennettTeam affiliationsJustice League DarkTeam 13Justice LeagueAbilitiesTraditional vampiric attributes such as immortality and healing, superhuman strength and speed, heightened senses (including night vision), h...

 

NacionalNama lengkapClube Desportivo NacionalJulukanOs Alvinegros (Putih dan Hitam)Berdiri1910StadionEstádio da Madeira,Funchal, Madeira(Kapasitas: 5,132)Ketua Rui AlvesManajer Manuel MachadoLigaPrimeira Liga2012–13Primeira Liga, 8th Kostum kandang Kostum tandang Kostum ketiga Clube Desportivo Nacional, biasa dipanggil Nacional atau juga Nacional da Madeira (pengucapan bahasa Portugis: [nɐsiuˈnaɫ dɐ mɐˈdɐjɾɐ]), merupakan sebuah tim sepak bola Portugal yang bermain di divisi u...

Sanskrit text on the performing arts Natya ShastraShiva as the Lord of DanceInformationReligionHinduismAuthorBharataLanguageSanskritPart of a series onHindu scriptures and texts Shruti Smriti List Vedas Rigveda Samaveda Yajurveda Atharvaveda Divisions Samhita Brahmana Aranyaka Upanishads UpanishadsRig vedic Aitareya Kaushitaki Sama vedic Chandogya Kena Yajur vedic Brihadaranyaka Isha Taittiriya Katha Shvetashvatara Maitri Atharva vedic Mundaka Mandukya Prashna Other scriptures Agamas Bhagavad...

 

1934 film by Alessandro Blasetti This article may require cleanup to meet Wikipedia's quality standards. The specific problem is: highly unconventional film article. Please help improve this article if you can. (November 2012) (Learn how and when to remove this message) 1860Directed byAlessandro BlasettiWritten byEmilio Cecchi Gino Mazzucchi Alessandro BlasettiProduced byEmilio CecchiStarringGiuseppe Gulino Aida Bellia Gianfranco Giachetti Mario FerrariCinematographyAnchise Brizzi Giulio De L...

 

2010 24 Hours of Daytona Previous: 2009 Next: 2011 Index: Races | Winners Track map of Daytona International Speedway The 2010 Rolex 24 at Daytona was the 48th running of the Rolex 24 at Daytona and was the first round of the 2010 Rolex Sports Car Series season. It took place between January 30–31, 2010. Rule changes With the increased field size for the 24 Hours of Daytona as compared to other events in the season, some full-time teams had expressed concern that a poor finish in the race ...

Fictional Dungeons & Dragons monster This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Slaad – news · newspapers · books · scholar · JSTOR (December 2015) (Learn how and when to remove this message) SlaadFirst appearanceFiend Folio (1981)In-universe informationTypeOutsiderAlignmentChaotic neutral The slaad...

 

FăgăraşKotaNegara RumaniaProvinsiBraşovStatusMunisipalitasPemerintahan • Wali kotaMănduc Constantin SorinPopulasi (2002) • Total40.126Zona waktuUTC+2 (EET) • Musim panas (DST)UTC+3 (EEST)Situs webhttp://www.primaria-fagaras.ro/ Făgăraş (Jerman: Fogarasch, Fugreschmarktcode: de is deprecated , bahasa Hongaria: Fogaras) adalah kota yang terletak di provinsi Braşov, Rumania. Kota ini memiliki jumlah penduduk sebesar 35.400 jiwa pada tahu...

 

本條目存在以下問題,請協助改善本條目或在討論頁針對議題發表看法。 此條目可能包含原创研究。 (2018年3月29日)请协助補充参考资料、添加相关内联标签和删除原创研究内容以改善这篇条目。详细情况请参见讨论页。 此條目需要补充更多来源。 (2010年2月4日)请协助補充多方面可靠来源以改善这篇条目,无法查证的内容可能會因為异议提出而被移除。致使用者:请搜索一�...

Kebun Botani KrakówInformasi UmumJenisKebun botaniLokasiKraków, PolandiaKoordinat-Tahun Berdiri1783Dioperasikan olehPemerintah KrakówStatusMilik Universitas Jagiellonian Kebun Botani Kraków atau yang juga dikenal sebagai Kebun Botani Universitas Jagielloniann adalah sebuah kebun botani yang terletak di kota Kraków, Polandia dan didirikan sejak tahun 1783. Kebun ini berada di arah Timur dari kota tua Stare Miasto dan memiliki luas 9.6 hektare, dan milik dari Universitas Jagiellonian. Kebu...

 

Belgian mounted police. Crime in Belgium is countered by the Belgian Police and other agencies. Crime by type Murder Further information: List of countries by intentional homicide rate In 2012, Belgium had a murder rate of 1.8 per 100,000 population.[1] There were a total of 182 murders in Belgium in 2012.[1] Theft Muggings, purse snatchings, and pocket picking occur frequently, particularly in major cities. Thieves often loiter in transportation hubs like the Metro (subway) ...

 

اضغط هنا للاطلاع على كيفية قراءة التصنيف البقر صورة أحد أنواع البقر في سويسرا حالة الحفظ مستأنسة التصنيف العلمي النطاق: حقيقيات النوى المملكة: الحيوانات الشعبة: الحبليات الطائفة: الثدييات الرتبة: شفعيات الأصابع الرتيبة: مجترات الفصيلة: البقريات الجنس: البقر الاسم العلمي B...

جزء من سلسلة مقالات حولالله في الإسلام مصطلحاتالتسبيح: سبحان الله التكبير: الله أكبر الحمد: الحمد لله التشهّد: لا إله إلّا الله تعابير مرتبطة جلَّ جلاله سبحانه وتعالى عزَّ وجلّ أخرى إنَّا لله بسم الله إن شاء الله ما شاء الله استغفر الله لا حول ولا قوة إلا بالله جزاك الله أعو�...

 

Currency of the Kingdom of Sicily 1805 Sicilian piastra coin The piastra was the distinct currency of the Kingdom of Sicily until 1815. History See also: History of coins in Italy In order to distinguish it from the piastra issued on the mainland Kingdom of Sicily (also known as the Kingdom of Naples), it is referred to as the Sicilian piastra as opposed to the Neapolitan piastra. These two piastra were equal, but were subdivided differently. The Sicilian piastra was subdivided into 12 tarì,...

 

Religion in Hungary Islam in Europeby percentage of country population[1]   90–100% AzerbaijanKosovoTurkey   70–90% AlbaniaKazakhstan   50–70% Bosnia and Herzegovina   30–40% North Macedonia   10–20% BulgariaFranceGeorgiaMontenegroRussia   5–10% AustriaSwedenBelgiumGermanyGreece LiechtensteinNetherlandsSwitzerlandUnited KingdomNorwayDenmark   4–5% ItalySerbia   2–4% LuxembourgMaltaSloveniaS...

American record label Fueled by Ramen LLCParent companyWarner Music GroupFounded1996; 28 years ago (1996)Founder John Janick Vinnie Fiorello Distributor(s)300 Elektra Entertainment (United States)Warner Music Group (International)GenreVariousCountry of originUnited StatesLocationNew York CityOfficial websiteelektra.com/fueledbyramen Fueled by Ramen LLC is an American record label owned by Warner Music Group and distributed by 300 Elektra Entertainment. The label, founded in ...

 

Sommeval Sommeval Vị trí trong vùng Champagne-Ardenne Sommeval Hành chính Quốc gia Pháp Vùng Grand Est Tỉnh Aube Quận Troyes Tổng Bouilly Liên xã aucune Xã (thị) trưởng M. Genevieve Rusak(2008) Thống kê Độ cao 210 m (690 ft) bình quân Diện tích đất1 9,57 km2 (3,69 dặm vuông Anh) INSEE/Mã bưu chính 10371/ 10320 Sommeval là một xã ở tỉnh Aube, thuộc vùng Grand Est ở phía bắc miền trung nước Phá...

 

Pour les articles homonymes, voir Euro 2009. Championnat d'Europe masculin de basket-ball 2009 Généralités Sport Basket-ball Organisateur(s) FIBA Europe Éditions XXXVIe championnat d'Europe Lieu(x) Pologne Date 7 au 20 septembre 2009 Participants 16 équipes Site(s) 7 (Gdańsk, Poznań, Varsovie, Wrocław, Bydgoszcz, Łódź, Katowice) Site web officiel eurobasket2009.org Palmarès Vainqueur Espagne Finaliste Serbie Meilleur joueur Pau Gasol Meilleur(s) marqueur(s) Pau Gasol Navigati...

2020–2023 police brutality protests For lists of protests, see Lists of George Floyd protests. For the social movement mainly involved in the protests, see Black Lives Matter. George Floyd protestsPart of the United States racial unrest (2020–present) and the Black Lives Matter movementClockwise from top: Protesters in Minneapolis where George Floyd was murdered and the unrest began Police and National Guard at a protest in Philadelphia, Pennsylvania Bystanders and firefighters at a torch...

 

У этого термина существуют и другие значения, см. Гаага (значения). Город и общинаГааганидерл. Den Haag / 's-Gravenhage Сверху вниз, слева направо: Сквер[нидерл.] в центре города;здание международного суда (Дворец мира); дворец Нордейнде;Пассаж[нидерл.]; королевский дворец Хёйс-тен-Б...