martes, 19 de mayo de 2009

ESTRUCTURALES

Adapter

Intención
Adapta una interfaz para que pueda ser utilizada por una clase que de otro modo no podría utilizarla.

Motivacion
Necesitamos reutilizar clases ajenas paranuestro sistema, pero aunque la funcionalidad de estas clases es la que deseamos, la interfaz no es compatible. Si no podemos o no queremos modificar las clases a reutilizar, necesitamos hacerlas compatibles con nuestro sistema.

Aplicabilidad

Se quiere utilizar una clase que llame a un método a través de una interface, pero quieres utilizarlo con una clase que no implementa ese interface. Modificar esa clase que implementa el interface no es una opción por un par de razones:
1. No tienes el código fuente de la clase.
2. La clase es una clase de propósito general, y es inapropiado para ella implementar un interface par un propósito específico.
Se quiere determinar dinámicamente que métodos de otros objetos llama un objeto.
Se quiere realizarlo sin que el objeto llamado tenga conocimientos de la otra clase de objetos.

Estructura


Participantes
Target: Define la interfaz especifica del dominio en el que se quiere hacer uso de la clase que se adapta.
Client: Utiliza objetos que implementan la interfaz definida por el target.
Adaptee: Presenta su interfaz original, que es la que se tiene que adaptar.
Adapter: Adapta la interfaz del objeto adaptado a la definida por el target.

Colaboraciones
Esta sección está compuesta por máximo seis (6) palabras o frases que describan los tópicos, áreas o temas más importantes del trabajo. Deben estar ordenadas alfabéticamente. La selección de palabras clave apropiadas permitirá la inclusión del artículo en índices internacionales así como la ubicación rápida del artículo por parte de un lector interesado.

Consecuencias
El cliente y las clases Adaptee permanecen independientes unas de las otras.
El patrón Adapter introduce una in dirección adicional en un programa . Como cualquier otra in dirección, contribuye a la dificultad implicada en la compresión del programa.
Se puede utilizar una clase Adapter para determinar cuales de los métodos de un objeto llama otro objeto.
Adaptadores de clase y el objeto tienen diferentes ventajas y desventajas. A class adapter Una clase adaptador

Adaptee se adapta al objetivo de la comisión a una clase concreta adaptador. Como consecuencia de ello, una clase
adaptador no funciona cuando se quiere adaptar una clase y todas sus subclases.

Adaptador permite anular algunas de Adaptee el comportamiento, ya que el adaptador es una subclase de Adaptee.
sólo introduce un objeto, y no puntero indirección adicional es necesaria para llegar a la adaptee.
Un objeto adaptador
permite a un único adaptador de trabajar con muchas Adaptees-es decir, la Adaptee sí mismo y todas sus subclases
(si procede). El adaptador también puede agregar funcionalidad a todos los Adaptees a la vez.
Adaptador se refieren a la subclase más que la propia Adaptee

Implementación
La implementación de una clase Adapter es más bien sencilla. Sin embargo, una cuestión que deberías considerar cuando implementes el patrón Adapter es como los objetos adapter conocen que instancia de la clase Adaptee llamar. Hay dos métodos:

1. Pasar una referencia a los objetos cliente como parámetro a los costructores de los objetos adapter o a uno de sus métodos. Esto permite al objeto adapter ser utilizado con cualquier instancia o posiblemente muchas instancias de la clase Adaptee.
Hacer la clase Adapter una clase interna de la clase Adaptee. Esto simplifica la asociación entre el objeto adapter y el objeto adaptee haciendolo automático.
También hace la asociación inflexible.

Código ejemplo
public interface ListModel {
int getSize();
Object getElementAt(int index);
}
public interface TableModel {
public int getRowCount();
// obtener número de filas
public int getColumnCount();
// obtener número de columnas
public Object getValueAt(int fil, int col);
// retorna valor del elemento fila fil y columna col
public String getColumnName(int col);
// retorna nombre de la columna col
}

Usos conocidos
El API de Java no incluye ningún objeto adapter público que este listo para utilizar. Incluye clases tales como java.awt.event.WindowAdapter que pretenden ser heredadas más que utilizarse directamente. La idea es que hay algunos interfaces escuchadores de eventos, tales como WindowListener, que declaran varios métodos. En muchos casos no todos los métodos necesitan ser implementados. El interface WindowListener declara ocho métodos que son llamados para proporcionar notificación sobre los ocho tipos diferentes de eventos de la ventana. A menudo uno o dos de estos tipos de eventos son de interés. Los métodos que corresponden a los eventos que no son de interés normalmente están dando implementaciones de no hacer nada. La clase WindowAdapter implementa el interface WindowListener e implementa los ocho métodos con implementaciones de no hacer nada. Una clase Adapter que hereda la clase WindowAdapter necesita implementar solamente los métodos que corresponden a los eventos que son de interés. Hereda las implementaciones de no hacer nada para el resto.

Patrones relacionados

Facade
La clase Adapter proporciona un objeto que actúa como un intermediario para llamar a los métodos entre los objetos cliente y uno de los otros objetos que no conocen a los objetos cliente. El patrón Facade proporciona un objeto que actúa como un intermediario para llamar a los métodos entre los objetos cliente y múltiples objetos que no conocen a los objetos cliente.
Iterator
El patrón Iterator es un versión especializada del patrón Adapter para acceder secuencialmente al contenido de una colección de objetos.
Proxy
El patrón Proxy, como el patrón Adapter, utiliza un objeto que es un sustituto por otro objeto. Sin embargo, un objeto proxy tiene el mismo interface que el objeto por el que es sustituido.
Strategy
El patrón Strategy es estructuralmente similar al patrón Adapter. La diferencia esta en el objetivo. El patrón Adapter permite a un objeto cliente exportar su función deseada originalmente para llamar al método de los objetos que implementan un interface particular. El patrón Strategy proporciona objetos que implementan un interface particular con el propósito de alterar o determinar el comportamiento de un objeto cliente.



Bridge

Intención
desacopla una abstracción de su implementación para que puedan variar independientemente.

Motivación
Cuando queremos que un objeto cambie su comportamiento, según cambia su estado, se presenta el problema de la complejidad de código.

Aplicabilidad
Se usa el patrón Bridge cuando:
Se desea evitar un enlace permanente entre la abstracción y su implementación. Esto puede ser debido a que la implementación debe ser seleccionada o cambiada en tiempo de ejecución.
Tanto las abstracciones como sus implementaciones deben ser extensibles por medio de subclases. En este caso, el patrón Bridge permite combinar abstracciones e implementaciones diferentes y extenderlas independientemente.
Cambios en la implementación de una abstracción no deben impactar en los clientes, es decir, su código no debe tener que ser recompilado.
(En C++) Se desea esconder la implementación de una abstracción completamente a los clientes. En C++, la representación de una clase es visible en la interface de la clase.
Se desea compartir una implementación entre múltiples objetos (quizá usando contadores), y este hecho debe ser escondido a los clientes.

Estructura

Participantes
Abstraction define una interface abstracta. Mantiene una referencia a un objeto de tipo Implementor.
RefinedAbstraction extiende la interface definida por Abstraction
Implementor define la interface para la implementación de clases. Esta interface no se tiene que corresponder exactamente con la interface de Abstraction; de hecho, las dos interfaces pueden ser bastante diferente. Típicamente la interface Implementor provee sólo operaciones primitivas, y Abstraction define operaciones de alto nivel basadas en estas primitivas.
ConcreteImplementor implementa la interface de Implementor y define su implementación concreta.

Colaboraciones
Abstraction emite los pedidos de los clientes a su objeto Implementor.
Consecuencias
Un objeto puede cambiar su implementación en tiempo de ejecución.
Cambios en la implementación no requerirán compilar de nuevo la clase Abstracción y sus clientes.
Se mejora la extensibilidad.
Se ocultan detalles de implementación a los clientes.

Implementación
Sólo un Implementor: en situaciones donde existe sólo una implementación, crear una clase Implementor abstracta no es necesario. Esto es un caso especial del patrón; hay una relación uno-a-uno entre Abstraction e Implementor. Sin embargo, esta separación es aún muy útil cuando un cambio en la implementación de una clase no debe afectar a sus clientes existente, es decir, ellos no deben ser recompilados, sólo relinkeados. En C++, la interface de la clase Implementor puede ser definida en un archivo header privado el cual no es proveído a los clientes. Esto permite esconder una implementación de una clase completamente de sus clientes.
Creando el objeto Implementor adecuado: ¿Cómo, cuándo y dónde que clase Implementor instanciar cuando hay más de una?Si Abstraction conoce todas las clases ConcreteImplementor puede instanciar una de ellas en su constructor; puede decidir cuál instanciar dependiendo de los parámetros del constructor.
Otra aproximación es elegir una implementación inicial por defecto y cambiarla después acorde al uso. También es posible delegar la decisión a otro objeto en conjunto.
Compartiendo implementadores: el estilo Handle/Body en C++ puede ser usado para compartir implementaciones de muchos objetos. Body almacena una cuenta de referencia que la clase Handle incrementa y decrementa. Usando herencia múltiple. Se puede usar herencia múltiple en C++ para asociar una interfaz con su implementación.
Creamos una clase Abstracción padre que sea abstracta, además de abstracciones concretas mediante clases que heredan de ella. Por otro lado se tienen las clases que implementan la funcionalidad con una estructura similar: una clase ImplementaciónAbstracta padre, y todas las clases hijas necesarias que implementan la funcionalidad de todas las maneras necesarias. La relación se da entre la clase abstracta Abstracción y la clase abstracta Implementación, delegando la primera la implementación en la segunda, que a su vez la delega en las implementaciones concretas.

Código ejemplo
//método getToolkit en Component

public Toolkit getToolkit() {
return getToolkitImpl();
}
final Toolkit getToolkitImpl() {
ComponentPeer peer = this.peer;
if ((peer != null) && ! (peer instanceof LightweightPeer)){
return peer.getToolkit();
}
Container parent = this.parent;
if (parent != null) {
return parent.getToolkitImpl();
}
return Toolkit.getDefaultToolkit();
}
//método getDefaultToolkit en la clase Toolkit

public static Toolkit getDefaultToolkit() {
String nm;
Class cls;
if (toolkit == null) {
try { nm = System.getProperty("awt.toolkit",
"sun.awt.motif.MToolkit");
try { cls = Class.forName(nm);
} catch (ClassNotFoundException e){..}
if (cls != null) toolkit = (Toolkit) cls.newInstance();
...
return toolkit;
}

Usos conocidos
El AppKit de NeXT usa un Bridge en la visualización de diferentes tipos de imágenes.
El DOM de KDE3 esta basado en un bridge (con otros patrones). Permite crear diferentes tipos de documentos usando la misma abstracción.
Patrones relacionados
AbstractFactory.
· Adapter.




Composite


Intención

Componer objetos en estructuras de árbol para representar jerarquías parte-todo.
Composite permite a los clientes tratar cada uno de los objetos y composiciones de objetos de manera uniforme.

Motivación
El problema que trata
Para constituir diagramas complejos desde componentes
simples en casos como un editor de dibujos, diseñador de
circuitos
Los objetos primitivos y los contenedores de ellos están en
diferentes maneras, aunque los clientes tratan ambos en la
misma manera.

Aplicabilidad
Cuando necesitamos representar la relación parte-todo

Cuando queramos que los clientes olviden la diferencia entre
las composiciones de objetos y los objetos individuales


Estructura


Participantes
Componente
Declara la interfaz para los clientes puedan acceder a lo objetos en la composición
Implementa comportamientos por defectos para todas las clases

Hoja
Representa los objetos hoja en la composición. No tienen hijos.

Define el comportamiento de los objetos primitivos en la composición

Compuesto
Define el comportamiento para los componentes que tienen
hijos
.
Almacena los componentes hijos


Implementa operaciones relacionadas a los hijos en la interfaz
de Componente
. Cliente

Manipula los objetos en la composición a través de la interfaz
de la clase Componente
.

Colaboraciones

Existen colaboraciones entre el cliente y
Componente

El cliente utiliza la interfaz para interactuar
con los objetos en la composición

Si el recibidor es una hoja: la petición se
trata directamente

Si el recibidor es un Compuesto: la petición
se pasa a sus hijos

Puede tener más operaciones extras


Consecuencias

Se define una jerarquía de clases con objetos
primitivos y compuestos

Simplifica las tareas del cliente. Puede tratar un
compuesto como un objeto primitivo

Facilita añadir nuevos componentes sin modificar
la estructura ni los códigos de clientes

Desventajas:

El diseño de programa puede ser demasiado
general

Difícil de restringir los componentes de un
compuesto.


Implementación


Temas para considerar en la implementación:

Referencias explícitas al padre

Es conveniente a tener la referencia al padre para simplificar el recorrido y administración hacia arriba

Compartir componentes

Para ahorrar espacio de almacenamiento

Será difícil a compartir cuando el componente tiene un sólo
padre

La solución aparece en el patrón Flyweight
Maximizar la interfaz de Componente.

Es bueno a definir más operaciones posibles en la clase
Componente tanto para Compuesto como para Hoja

Definir operaciones por defectos en Componente y luego las
subclases puedan redefinirlas si son necesarias.

Dónde declarar las operaciones para administrar los hijos

Definir en la raíz (Componente): mejor transparencia peor
seguridad porque los clientes pueden hacer cosas raras

Definirlas en Compuesto: mejor seguridad pero pierde la
transparencia

Una solución: verificar en la interfaz si lo que pide es un
Compuesto o una hoja.

Código ejemplo

public abstract class Componente
{
protected String nombre;
public Componente (String nombre)
{
this.nombre = nombre;
}
abstract public void Agregar(Componente c);
abstract public void Remover(Componente c);
abstract public void Mostrar(int profundidad);
}
class Compuesto extends Componente
{
private ArrayList hijo = new ArrayList();
public Compuesto (String name)
{
super(name);
}
@Override
public void Agregar(Componente componente)
{
hijo.add(componente);
}
@Override
public void Remover(Componente componente)
{
hijo.remove(componente);
}
@Override
public void Mostrar(int profundidad)
{
System.out.println(nombre + " nivel: " + profundidad);
for (int i = 0; i < raiz =" new" comp =" new" l =" new" style="font-weight: bold;" size="4">Usos conocidos

n Java:
· las clases java.awt.Component(Componente)
· java.awt.Container(Contenedor)
· java.awt.Panel(Contenedor concreto)
· java.awt.Button(Boton)

Patrones relacionados
Chain of Responsibility: para crear enlace entre la

clase componente y su padre

Decorator: se suelen utilizar con composite.
Normalmente tienen una clase pariente en comúm

Flyweight: nos permite compartir componentes, pero
sin referencias a su pariente

Iterator: se puede utilizar para recorrer los
compuestos

Visitor: puede localizar operaciones y
comportamientos sin distribuirlos entre las clases de
Compuesto y Hoja



Decorator

Intención
Fija responsabilidades adicionales a un objeto dinámicamente. Decoreirtors provee una alternativa flexible a las subclasses para extender la funcionalidad.

Motivación
A veces se desea adicionar responsabilidades a un objeto pero no a toda la clase. Las responsabilidades se pueden adicionar por medio de los mecanismos de Herencia, pero este mecanismo no es flexible porque la responsabilidad es adicionada estáticamente. La solución flexible es la de rodear el objeto con otro objeto que es el que adiciona la nueva responsabilidad. Este nuevo objeto es el Decorator.

Aplicabilidad

Añadir objetos individuales de forma dinámica y transparente
Responsabilidades de un objeto pueden ser retiradas
Cuando la extensión mediante la herencia no es viable
Hay una necesidad de extender la funcionalidad de una clase, pero no hay razones para extenderlo a través de la herencia.
Hay la necesidad de extender dinámicamente la funcionalidad de un objeto y quizás quitar la funcionalidad extendida.

Estructura

Participantes
Component
Define la interface de los objetos a los que se les pueden adicionar responsabilidades dinámicamente.
ConcreteComponent
Define el objeto al que se le puede adicionar una responsabilidad.
Decorator
Mantiene una referencia al objeto Component y define una interface de acuerdo con la interface de Component.
ConcreteDecorator
Adiciona la responsabilidad al Component.

Colaboraciones

Decorator envía las solicitudes a su componente de objeto. Opcionalmente puede realizar operaciones adicionales antes y después del envío de la solicitud.

Consecuencias
Ventajas

1.Es más flexible que la Herencia estática.
2.Permite que la adicion de nuevas responsabilidades (nuevas clases de Decorators) independiente de las clases los Objetos que ellas extienden.
Desventajas
1.Un Decorator y su Component no son idénticos. Desde el punto de vista de la identidad de los objetos, un DecoratorComponent no es identico al Component. Por esto no se puede confiar en en la identidad de los objetos cuando se usan Decorators
2.El patrón Decorator hace que hayan muchos objetos pequeños que son muy parecidos.

Implementación
El patrón Decorator soluciona este problema de una manera mucho más sencilla y extensible.
Se crea a partir de Ventana la subclase abstracta VentanaDecorator y, heredando de ella, BordeDecorator y BotonDeAyudaDecorator. VentanaDecorator encapsula el comportamiento de Ventana y utiliza composición recursiva para que sea posible añadir tantas "capas" de Decorators como se desee. Podemos crear tantos Decorators como queramos heredando de VentanaDecorator.


Código ejemplo
public abstract class FilterReader extends Reader {
protected Reader in;
protected FilterReader(Reader in) {
super(in);
this.in = in; }
public int read() throws IOException {
return in.read(); }
… }

public class ConversorMayúsculas extends FilterReader {
public ConversorMayúsculas (Reader in) {
super(in);
}
public int read() throws IOException {
int c = super.read();
if (c != -1) return Character.toUpperCase((char)c);
else return c;
}
}

Usos conocidos
Muchos toolkits de interfaz de usuarios orientado aobjetos utilizan Decorator para añadir decoraciones graficas.

Patrones relacionados
Adapter: Este patrón cambia las responsabilidades y la interfaces de un objeto.
1.Composite: Un DECORATOR se puede mirar como un COMPOSITE de un solo elemento.
2.Strategy: Este patrón permite cambiar el contenido de los Objetos par agregar responsabilidades.

Facade

Intención
Proporcionar una interfaz unificada a un conjunto de interfaces en un subsistema. Fachada define una interfaz de alto nivel que hace que el subsistema sea más fácil de usar.

Motivación
Minimizar la comunicación y las dependencias entre subsistemas

Aplicabilidad
El uso de este patrón esta recomendado para
Simplicar el uso y comprensión de una librería software.
Encapsular un interfaz de librería poco amigable en un interfaz más coherente o mejor estructurado.
Centralizar las dependencias externas hacia la librería en uno o pocos puntos de entrada.

Estructura


Participantes

Fachada
subsistema o sabe que las clases son responsables de una solicitud.
delegados a las solicitudes de cliente subsistema objetos.
subsistema de clases
implementar la funcionalidad del subsistema.
manejar el trabajo asignado por la Fachada objeto.
no tienen conocimiento de la fachada, es decir, no mantener las referencias a la misma.

Colaboraciones
Los clientes se comunican con el subsistema mediante el envío de peticiones a la fachada, que reenvía a los subsistema objeto (s). A pesar de que el subsistema de objetos de realizar el trabajo real, la fachada puede tener que hacer su propio trabajo de traducir su interfaz a las interfaces del subsistema.
Los clientes que usan la fachada no tiene acceso a su subsistema de objetos directamente.

Consecuencias

la ventaja del patrón facade es que proporciona una interfaz mas simple para un sistema complejo sin reducir las opciones proporcionadas por el conjunto del sistema. Esta interfaz protege al cliente de la sobreabundancia de opciones.
El patrón Facade traduce las peticiones del cliente a los subsistema que pueden cumplir esas peticiones. La mayor parte de las veces, una petición sera delegada en mas de un sistema. Como el cliente Solo interactúa con el facade, el funcionamiento interno puede ser modificado, mientras que el cliente del facade puede permanecer igual.
El patrón Facade fomenta el bajo acoplamiento entre el cliente y los subsistemas. También puede ser utilizado para reducir el acoplamiento entre los subsistemas. Todos los subsistemas pueden tener su propio Facade, y las otras partes del sistema pueden utilizar ese Facade para comunicarse con el subsistema.

Implementación

Se puede reducir aún más el acoplamientohaciendo que la fachada sea una clase abstracta, de forma que se pueda escogerentre distintas implementaciones del subsistema


Código ejemplo





Usos conocidos

Las clases Font y Graphics de las librerías estandar de Java que proporcionan la funcionalidad básica para manipulación de fuentes y graficos aislando al usuario, en las operaciones más comunes, de la complejidad subyacente. Otros ejemplos incluyen determinados interfaces de librerías GIS o librerías matemáticas.

Patrones relacionados
Abstract factory : para simplificar el acceso a los distintos objetos creados por la fabrica , esta también puede crear un objeto facade para todos ellos.
Mediator: los patrones mediator y facade son muy parecidos . La diferencia reside en la intención y en la implementación. El patrón mediator ayuda a facilitar la comunicación entre los componentes y sus comportamientos adicionales.
Singleton: el patrón facade utiliza el patrón Singleton para garantizar un punto de entrada único y globalmente accesible para un subsistema.

Flyweight

Intención
Compartir estados para soportar un gran número de objetos pequeños aumentando la eficiencia en espacio.

Motivación
El patrón flyweight describe como almacenar un gran número de objetos sin un gran coste.
Para conseguir esto se utilizan objetos que almacenan los estados compartidos y que pueden ser usados por varios objetos simultáneamente.

Aplicabilidad

Se debe aplicar este patrón cuando se cumplen todas estas características:
Se utiliza un gran número de objetos
El coste de almacenamiento es alto debido a la cantidad de objetos
La mayoría de los estados de los objetos pueden ser creados como comunes.
Muchos objetos pueden ser reemplazados por unos pocos una vez que han sido borrados los estados no comunes.
La aplicación no depende de la identidad de los objetos.

Estructura

Participantes
Flyweight
Declara una interfaz a través de la cual los flyweights pueden recibir y actuar sobre los estados no compartidos.
ConcreteFlyweight
Implementa la interfaz Flyweight y almacena los estados compartidos, si los hay. Un objeto ConcreteFlyweight debe ser compartible. Cualquier estado que almacene debe ser intrínseco; es decir, debe ser independiente de su contexto.
UnsharedConcreteFlyweight
No todas las subclases de Flyweight tienen por qué ser compartidas. La interfaz Flyweight permite que se comparta; no lo fuerza. Es común que los objetos de esta clase tengan hijos de la clase ConcreteFlyweight en algún nivel de su estructura.
FlyweightFactory
Crea y gestiona los objetos flyweight.
Garantiza que los objetos flyweight se comparten de forma apropiada. Cuando un cliente solicita un flyweight, el objeto de la clase FlyweightFactory proporciona una instancia existente, o crea una.
Client
Contiene referencias a los flyweights.
Calcula o almacena los estados no compartidos de los flyweights.

Colaboraciones

Un objeto flyweight debe ser clasificado como compartido o no compartido. Los compartidos se almacenan en el objeto ConcreteFlyweight; los no compartidos se almacenan o se calculan en el objeto Cliente. Los clientes pasan este estado al objeto flyweight cuando invocan sus operaciones.
Los clientes no deberían instanciar objetos de la clase ConcreteFlyweight directamente. Deben obtenerlos exclusivamente del objeto FlyweightFactory para garantizar que son compartidos apropiadamente.

Consecuencias
A primera vista , la ventaja que se obtiene es que se reduce el numero de objetos que hay que gestionar. Esto puede ahorrar mucho espacio, tanto en memoria como en los dispositivos de almacenamiento en caso de que sean objetos persistentes.
Se ahorra mas espacio aun si la información de contexto para los objetos Flyweight se calcula en vez de tener la almacenada, sin embargo , esto nos lleva al inconveniente de este patrón: el costo en tiempo de ejecución.
En lugar de almacenar muchos objetos, los clientes tienen que calcular el contexto y proporcionar esa información a los objetos Flyweight. Los Flyweight utilizan esta información para proporcionar funciones. Si se maneja menos objetos y se implementa correctamente, se incrementa el rendimiento en tiempo de ejecución . Obsérvese que si hay, poca información de contexto y el objeto Flyweight es grande , el ahorro es significativo.

Implementación

Crear una clase PelotaFlyweight, que contendrá la información común (radio y color) y otra clase PelotaConcreta, que contendrá las coordenadas concretas de cada pelota y una referencia a un objeto de tipo PelotaFlyweight.
Al crearse instancias de PelotaConcreta, se les deberá proveer de referencias a la instancia de PelotaFlyweight adecuada a nuestras necesidades.
En este caso solamente tendríamos una instancia de PelotaFlyweight, puesto que hemos dicho que todas nuestras pelotas tienen el mismo radio y color, pero pensando en un ejemplo en el que tuviéramos varios grupos de pelotas, y dentro de cada uno de los cuales se compartieran el radio y el color, se puede utilizar Flyweight conjuntamente con el patrón Factory, de tal modo que este último, en el momento en que se le soliciten instancias de PelotaConcreta con determinadas características (mismo radio y color que el solicitado), compruebe si ya existe un PelotaFlyweight con ese radio y color, y devuelva esa referencia o, en caso de que no exista, la cree y la registre. El patrón Factory se encargaría de gestionar los PelotaFlyweight existentes.

Código ejemplo
public class Elemento {
public Elemento() {..}
public void mostrar (Window w, ElemContexto ec) {..}
public void setFont (Font f, ElemContexto ec) {..}
public Font getFont (ElemContexto ec) {..}
public void insert (ElemContexto ec, Elemento e) {..}
...
}
public class Caracter extends Elemento {
char code;
public Caracter(char c) {..}
public void mostrar (Window w, ElemContexto ec) {..}
}


public class ElemContexto {
int index;
Btree fonts;

public ElemContexto() {...}
public void setFont (Font f, int span) {..}
public Font getFont () {..}
public void insert (int cant) {..}
public void next (){..}
}

Usos conocidos

Strings
Pool de objetos compartidos para literales de tipo String
“hola” = “hola”
Método intern() en clase String: dado un string lo añade al pool
String c = (a+b).intern
Bordes de Swing

Patrones relacionados Composite, utilizado para componer objetos en estructural de árbol para representar jerarquías.

Proxy, que proporciona un intermediario de otro objeto para controlar el acceso a este. º
Facade, que proporciona una interfaz unificada para un conjunto de interfaces de un subsistema.

Proxy


Intención
Proporcionar un sustituto o marcador de posición de otro objeto para controlar el acceso a ella.

Motivación
Diferir el coste de crear un objeto hasta que sea necesario usarlo: creación bajo demanda.
Un editor de documentos que incluyen objetos gráficos.
¿Cómo ocultamos que una imagen se creará cuando se necesite?: manejar el documento requiere conocer información sobre la imagen.
Hay situaciones en las que un cliente no referencia o no puede referenciar a un objeto directamente, pero necesita interactuar con él.
Un objeto proxy puede actuar como intermediario entre el objeto cliente y el objeto destino.
El objeto proxy tiene la misma interfaz como el objeto destino.
El objeto proxy mantiene una referencia al objeto destino y puede pasarle a él los mensajes recibidos (delegación).
Retrasar la operación de una clonación de una tabla hasta conocer que es realmente necesaria. Se desea clonar la tabla para evitar mantener un bloqueo un largo período de tiempo: operación costosa. Se puede crear una clase que encapsule la tabla y sólo clone cuando sea necesario.
Mantenimiento de los servicios ante los fallos.
Materialización perezosa de tuplas en objetos.

Aplicabilidad

Siempre que hay necesidad de referenciar a un objeto mediante una referencia más rica que un puntero o una referencia normal.
Situaciones comunes;

Proxy acceso remoto (acceso a un objeto en otro espacio de direcciones)
Proxy virtual (crea objetos grandes bajo demanda)
Proxy para protección (controlar acceso a un objeto)
Referencia inteligente (smart reference, proporciona operaciones adicionales)

Estructura

Participantes
Sujeto:
Define la interfaz común para el RealSubject y el Proxy, de modo que pueda usarse un Proxy en cualquier sitio en el que se espere un RealSubject.

RealSubject:
Define el objeto real representado.
Proxy:
Mantiene una referencia que permite al Proxy acceder al objeto real.
Proporciona una interfaz idéntica a la del sujeto, de manera que un Proxy pueda ser sustituido por el sujeto real.
Controla el acceso al sujeto real, y puede ser responsable de su creación y borrado.

Colaboraciones
Proxy reenvía las solicitudes de RealSubject en su caso, dependiendo del tipo de proxy.
Consecuencias
Introduce un nivel de indirección para:

Un proxy remoto oculta el hecho que objetos residen en diferentes espacios de direcciones.
Un proxy virtual tales como crear o copiar un objeto bajo demanda.
Un proxy para protección o las referencias inteligentes permiten realizar tareas de control sobre los objetos accedidos.

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

Código ejemplo
package com.autentia.adictos.proxy;

public interface Manager {
public void save(Object obj);
public void remove(Integer id);
} package com.autentia.adictos.proxy;

public class UserManagerImpl implements Manager {

public void save(Object obj) {
System.out.println("I save user Objects");
}

public void remove(Integer id) {
System.out.println("I remove user objects");
}

}package com.autentia.adictos.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ManagerHandler implements InvocationHandler {

Manager realManager = null;

public ManagerHandler(Manager realManager) {
this.realManager = realManager;
}

/* Este es el método callback que será invocado previamente a cada método de los managers. */
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

System.out.println("A Manager is being invoked:"+method.getName());

// Continuamos invocando al Manager real.
return method.invoke(realManager,args);
}

}package com.autentia.adictos.proxy;

import java.lang.reflect.Proxy;

public class FactoryManager {

public Manager createManager(Class claseManager) {

Manager realManager = null;

try {
// Creamos un objeto de la clase que recibimos.
realManager = (Manager)claseManager.newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}

/* Creamos el CallBack Handler y le pasamos el objeto real para ser invocado posteriormente en su método invoke. */

ManagerHandler handler = new ManagerHandler(realManager);

// Creamos el proxy.
Class[] interfacesQueEncapsulo = new Class[] {Manager.class};
return (Manager)Proxy.newProxyInstance(
claseManager.getClassLoader(),
interfacesQueEncapsulo,handler);
}
}package com.autentia.adictos.proxy;

public class Test {

public static void main(String[] args) {
// Creamos ahora la factoria
FactoryManager factory = new FactoryManager();

// Usamos la factoria para crear un Proxy sobre UserManagerImpl
Manager manager = factory.createManager(UserManagerImpl.class);

Object obj = new Object();
// Invocamos a los métodos:
manager.save(obj);
manager.remove(1);

}

}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

openTransaction();

Object obj = method.invoke(realManager,args);

closeTransaction();

return obj;
}


Usos conocidos


Patrones relacionados

Adapter: un adapter proporciona una interfaz frontal de un objeto especifico, de manera similar a como lo hace el patron Proxy. Sin embargo, el patron Proxy proporciona la misma interfaz para el objeto, y el patron Adapter proporciona una interfaz diferente.

1 comentario:

  1. Borgata Hotel Casino & Spa in Atlantic City, NJ - MapYRO
    Casino Hotel · 1 Borgata Way. Atlantic City, 김천 출장안마 NJ 08401. Directions · (609) 317-1000. Call 의왕 출장샵 Now 대전광역 출장안마 · More Info. Hours, Accepts Credit 구리 출장샵 Cards,  Rating: 영주 출장안마 2.5 · ‎1,181 votes · ‎Price range: $231

    ResponderEliminar