lunes, 25 de mayo de 2009
Patrones Estructurales
Patron Proxy
PROXY |
1. CLASIFICACIÓN DEL PATRÓN
Patrón Estructural.
2. INTENCIÓN
Proporcione un sustituto o un prototipo para otro objeto al acceso del control a él.
3. CONOCIDO TAMBIÉN
Surrogate.
4. MOTIVACIÓN
Una razón del acceso que controla a un objeto es diferir el coste completo de su creación e inicialización hasta que necesitemos realmente utilizarlo.
Considere un redactor del documento que pueda encajar objetos gráficos en un documento. Algunos objetos gráficos, como imágenes de trama grandes, pueden ser costosos crear. Pero la apertura de un documento debe ser rápida, así que debemos evitar crear todos los objetos costosos inmediatamente cuando se abre el documento. Este no es necesario de todos modos, porque no todos estos objetos serán visibles en el documento al mismo tiempo. Estos apremios sugerirían el crear de cada objeto costoso a pedido, que en este caso ocurre cuando una imagen llega a ser visible. ¿Pero qué ponemos en el documento en lugar de la imagen? Y ¿cómo puede ocultamos el hecho de que crear la imagen a pedido para nosotros no complica el editor implementación? Esta optimización no debería afectar el formato y representación del código.
5. POSIBLES APLICACIONES PARA EL PROXY
Se debe usar el patrón Proxy cuando:
· Un proxy remoto proporciona provee una representación local de un objeto en una dirección diferente.
· Un proxy virtual crea objetos costosos a pedido.
· Un proxy de protección controla el acceso al objeto original. Los poderes de la protección son útiles cuando los objetos deben tener diversos derechos de acceso.
· Una referencia apropiada es un reemplazo para un indicador pelado que se realice acciones adicionales cuando un objeto está alcanzado. Las aplicaciones típicas incluyen o que cuenta el número de referencias al objeto verdadero para poderlo liberar automáticamente cuando no hay referencias (también llamadas los indicadores elegantes [Ede92]). o que carga un objeto persistente en memoria cuando este primero se refirió. o que comprueba que el objeto verdadero es bloqueado antes de este tuvo acceso para asegurarse de que ningún otro objeto puede cambiarlo.
6. ESTRUCTURA
La estructura básica que maneja el proxy está compuesta por:
Fig. 1. Diagrama de clases del modelo de uso del Proxy.
7. PARTICIPANTES
· Proxy: mantiene una referencia que deja al proxy acceder al objeto real, proxy puede referir a un sujeto si el sujeto real y el sujeto tienen la misma interfaz. Provee una interfaz idéntica a la del sujeto con eso proxy puede ser sustituido por el sujeto real. Controla el acceso al sujeto real y puede ser responsable de crearlo y borrarlo.
· Subject: define la interfaz común para el realsubject y proxy con eso proxy puede ser usado en cualquier lugar que un realsubject es esperado.
· Realsubject: define el objeto real que el proxy representa.
8. COLABORACIONES
El proxy transmite a peticiones RealSubject cuando es apropiado, dependiendo de la clase de proxy.
9. CONSECUENCIAS
El patrón proxy tiene las siguientes consecuencias:
· Un proxy alejado puede ocultar el hecho de que un objeto reside en un diverso espacio de dirección.
· Un proxy virtual puede realizar optimizaciones tales como crear un objeto a pedido.
· Ambos el proxy de protección y las referencias inteligentes permiten tareas adicionales de las necesidades comunes cuando un objeto es accesado.
· Hay otra optimización que el patrón proxy puede ocultar del cliente. es llamado copia-en-escribe, y es relacionado con la creación a pedido. El copiado de un objeto grande y complicado puede ser una operación costosa. Si la copia nunca se modifica, entonces no hay ninguna necesidad de incurrir en este coste. Usando un proxy para posponer el proceso de copiado, nos aseguramos de que pagamos el precio de copiar el objeto solamente si este es modificado.
10. IMPLEMENTACIÓN
Para la implementación del Proxy es recomendable usar algunas “técnicas” para facilitar su uso.
· Sobrecargar al operador del acceso del miembro en C++. Ayudas de C++ que sobrecargan al operador ->, el operador del acceso del miembro. Sobrecargar a este operador le deja realizar el trabajo adicional siempre que un objeto no este referenciado. Esto puede ser provechoso para ejecutar algunas clases de proxy; el proxy se comporta apenas como un indicador.
· Usando doesNotUnderstand en Smalltalk. El smalltalk proporciona un gancho que usted pueda utilizar para apoyar la expedición automática de peticiones. El smalltalk llama el doesNotUnderstand: aMessage cuando un cliente envía un mensaje a un receptor que no tenga ningún método correspondiente. La clase del proxy puede redefinir doesNotUnderstand para remitir el mensaje a su tema.
· Proxy no tiene que saber siempre el tipo de tema verdadero. Si una clase del proxy puede ocuparse de su tema solamente a través de un interfaz abstracto, entonces no hay ninguna necesidad de hacer una clase del proxy para cada clase de RealSubject; el proxy puede interactuar con todo las clases del RealSubject uniformemente. Pero si los proxys van a ejemplificar RealSubjects (tal como adentro un proxy virtual), después ellos tienen que saber la clase concreta.
11. CÓDIGO DE EJEMPLO
class Graphic {
public:
virtual ~Graphic();
virtual void Draw(const Point& at) = 0;
virtual void HandleMouse(Event& event) = 0;
virtual const Point& GetExtent() = 0;
virtual void Load(istream& from) = 0;
virtual void Save(ostream& to) = 0;
protected:
Graphic();
};
class Image : public Graphic {
public:
Image(const char* file); // loads image from a file
virtual ~Image();
virtual void Draw(const Point& at);
virtual void HandleMouse(Event& event);
virtual const Point& GetExtent();
virtual void Load(istream& from);
virtual void Save(ostream& to);
private:
// ...
};
class ImageProxy : public Graphic {
public:
ImageProxy(const char* imageFile);
virtual ~ImageProxy();
virtual void Draw(const Point& at);
virtual void HandleMouse(Event& event);
virtual const Point& GetExtent();
virtual void Load(istream& from);
virtual void Save(ostream& to);
protected:
Image* GetImage();
private:
Image* _image;
Point _extent;
char* _fileName;
};
ImageProxy::ImageProxy (const char* fileName) {
_fileName = strdup(fileName);
_extent = Point::Zero; // don't know extent yet
_image = 0;
}
Image* ImageProxy::GetImage() {
if (_image == 0) {
_image = new Image(_fileName);
}
return _image;
}
12. USOS CONOCIDOS
El ejemplo del proxy virtual en la sección de la motivación es de las clases del bloque hueco del texto de ET++. NEXTSTEP [Add94] utiliza los proxys (casos de la clase NXProxy) como local representantes para los objetos que pueden ser distribuidos. Un servidor crea los proxys para los objetos alejados cuando los clientes los piden. Al recibir un mensaje, el poder lo codifica junto con sus discusiones y después transmite al mensaje codificado el tema alejado. Semejantemente, el tema codifica cualquier resultado de vuelta y lo envía de nuevo al objeto de NXProxy.
13. PATRONES ASOCIADOS
Al patrón proxy se le relaciona frecuentemente con los patrones; Adapter, Decorator, iterator.
REFERENCIAS BIBLIOGRÁFICAS
Design Patterns. Elements of Reusable Object-Oriented Software - Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides - Addison Wesley (GoF- Gang of Four)
Thinking in patterns in java – Bruce Eckel
Patterns in Java - Mark Grand – Wiley
Patron Flyweight
FLY WEIGHT |
1. CLASIFICACIÓN DEL PATRÓN
Patrón Estructural.
2. INTENCIÓN
Utiliza la distribución para apoyar una gran cantidad de objetos de grano fino eficientemente.
3. MOTIVACIÓN
Algunos usos podían beneficiarse de usar objetos a través de su diseño, pero una puesta en práctica ingenua sería prohibitivo costosa.
Por ejemplo, la mayoría de las puestas en práctica del redactor del documento tienen el formato de texto y medios de compaginación que se modularizan hasta cierto punto. Redactores orientados al objeto del documento utilice típicamente los objetos para representar elementos encajados como las tablas y las figuras. Sin embargo, detienen justo antes generalmente el usar de un objeto para cada carácter en documento, aunque el hacer tan promovería flexibilidad en los niveles más finos en el uso. Los caracteres y los elementos encajados podían entonces ser tratados uniformemente con respecto a cómo se dibujan y se dan formato. El uso se podía ampliar para apoyar nuevos juegos de caracteres sin disturbar la otra funcionalidad. La aplicación de la estructura del objeto podría copiar la estructura física del documento. El diagrama siguiente demuestra cómo un redactor del documento puede utilizar objetos para representar caracteres.
4. POSIBLES APLICACIONES PARA EL FLY WEIGHT.
Se debe usar el patrón Fly Weight cuando:
· Un uso utiliza una gran cantidad de objetos
· Los costes de almacenaje son altos debido a la cantidad escarpada de objetos.
· La mayoría del estado de objeto se puede hacer extrínseco.
· Muchos grupos de objetos se pueden substituir por relativamente pocos objetos compartidos una vez que se quita el estado extrínseco.
· El uso no depende de identidad del objeto. Puesto que los objetos del flyweight pueden ser compartidos, las pruebas de la identidad volverán verdad para conceptual distinto objetos.
5. ESTRUCTURA
La estructura básica que maneja el Flyweight está compuesta por:
Fig. 1. Diagrama de clases del modelo de uso del Flyweight.
6. PARTICIPANTES
· Fly Weight: declara una interface por la cual Flyweight puede recibir y actuar en un estado extrínseco.
· ConcreteFlyweight: implementa la interfaz del flyweight adhiere un almacenaje para el estado intrínseco, si lo hay. Un objeto concreteflyweight debe ser compartible. Cualquier estado que guarde debe ser intrínseco; es decir, debe depender del contexto del objeto de concreteflyweight.
· UnsharedConcrteFlyweight: no todas las subclases del flyweight necesitan ser compartidas. La interfaz del flyweight hace posible el intercambio; no lo forza. Es común para objetos UnsharedConcreteFlyweight tener objetos ConcreteFlyweight como hijos en algún nivel de la estructura del objeto flyweight.
· FlyweightFactory: crea y maneja los objetos flyweight. Asegura que los flyweights sean compartidos apropiadamente. Cuando el cliente requiere un flyweight, el objeto de la factoría suple una instancia existente o crea una, si no hay alguna ya creada.
· Client: mantiene una referencia de flyweight (s), computa o guarda el estado extrínseco de flyweight (s).
7. COLABORACIONES
Indique que un flyweight necesita funcionar debe ser caracterizado como intrínseco o extrínseco. El estado intrínseco se almacena en los patrones del diseño de ConcreteFlyweight objeto; el estado extrínseco es almacenado o computado por los objetos de Client. Los clientes pasan este estado al flyweight cuando invocan sus operaciones.
Los clientes no deben ejemplificar ConcreteFlyweights directamente. Los clientes deben obtener los objetos de ConcreteFlyweight exclusivamente del objeto de FlyweightFactory para asegurarse que los comparten correctamente.
8. CONSECUENCIAS
Los flyweights pueden introducir los costes run-time asociados a la transferencia, a encontrar, y/o al estado extrínseco computacional, especialmente si fue almacenado antes como estado intrínseco.
Sin embargo, tales costes son compensados por los ahorros de espacio, que aumentan mientras que comparten a más flyweights. Los ahorros del almacenaje son una función de varios factores:
· la reducción en el número total de casos que viene de la distribución · la cantidad de estado intrínseco por objeto
· si el estado extrínseco está computado o almacenado. Comparten a más flyweights, mayores son los ahorros del almacenaje. Los ahorros aumentan con la cantidad de estado compartido.
Los ahorros más grandes ocurren cuando los objetos utilizan cantidades substanciales de estado intrínseco y extrínseco, y el estado extrínseco se puede computar algo que almacenado. Entonces usted excepto en almacenaje de dos maneras: La distribución reduce el coste del estado intrínseco, y usted negocia el estado extrínseco por tiempo del cómputo.
9. IMPLEMENTACIÓN
Para la implementación del Flyweight es recomendable usar algunas “técnicas” para facilitar su uso.
· Eliminación del estado extrínseco. El patrón aplicabilidad es determinado en gran parte por cómo es fácil es identificar el estado extrínseco y quitarlo de objetos compartidos. Eliminación del estado extrínseco no ayuda a reducir costes de almacenaje si hay tantas diversas clases de estado extrínseco pues hay objetos antes de compartir. Idealmente, el estado extrínseco se puede computar de una estructura separada del objeto, una con requisitos de almacenaje lejos más pequeños. Los ahorros del almacenaje son una función de varios factores: · la reducción en el número total de casos que viene de la distribución · la cantidad de estado intrínseco por objeto · si el estado extrínseco está computado o almacenado. Comparten a más flyweights, mayores son los ahorros del almacenaje. Los ahorros aumentan con la cantidad de estado compartido. Los ahorros más grandes ocurren cuando los objetos utilizan cantidades substanciales de estado intrínseco y extrínseco, y el estado extrínseco se puede computar algo que almacenado. Entonces usted excepto en almacenaje de dos maneras: La distribución reduce el coste del estado intrínseco, y usted negocia el estado extrínseco por tiempo del cómputo.
· Objetos compartidos de manejo. Porque se comparten los objetos, los clientes no los ejemplifica directamente. FlyweightFactory deja a clientes localizar a flyweight particular. Los objetos de FlyweightFactory utilizan a menudo un almacén asociativo para dejar a clientes mirar para arriba a flyweights del interés. Por ejemplo, la fábrica del flyweight en el ejemplo del redactor del documento puede guardar una tabla de flyweights puestos en un índice por códigos de carácter. El encargado vuelve al flyweight apropiado dado su código, creando al flyweight si no existe ya.
10. CÓDIGO DE EJEMPLO
class Glyph {
public:
virtual ~Glyph();
virtual void Draw(Window*, GlyphContext&);
virtual void SetFont(Font*, GlyphContext&);
virtual Font* GetFont(GlyphContext&);
virtual void First(GlyphContext&);
virtual void Next(GlyphContext&);
virtual bool IsDone(GlyphContext&);
virtual Glyph* Current(GlyphContext&);
virtual void Insert(Glyph*, GlyphContext&);
virtual void Remove(GlyphContext&);
protected:
Glyph();
};
class Character : public Glyph {
public:
Character(char);
virtual void Draw(Window*, GlyphContext&);
private:
char _charcode;
};
class GlyphContext {
public:
GlyphContext();
virtual ~GlyphContext();
virtual void Next(int step = 1);
virtual void Insert(int quantity = 1);
virtual Font* GetFont();
virtual void SetFont(Font*, int span = 1);
private:
int _index;
BTree* _fonts;
};
const int NCHARCODES = 128;
class GlyphFactory {
public:
GlyphFactory();
virtual ~GlyphFactory();
virtual Character* CreateCharacter(char);
virtual Row* CreateRow();
virtual Column* CreateColumn();
// ...
private:
Character* _character[NCHARCODES];
};
11. USOS CONOCIDOS
El concepto de objetos del flyweight primero fue descrito y exploró como diseño técnica en las entrevistas 3.0 [CL90]. Sus reveladores construyeron un redactor de gran alcance del documento llamado doc. como prueba del concepto [CL92]. El doc. utiliza objetos del glyph para representar cada carácter en el documento. El redactor construye un caso del Glyph para cada carácter en un estilo particular (que defina sus cualidades gráficas); por lo tanto un character' el estado intrínseco de s consiste en el código de carácter y su información del estilo (un índice en una tabla del estilo) .4 que significa solamente la posición es extrínseca, haciendo el doc. rápido. Los documentos son representados por un documento de la clase, que también actúa como FlyweightFactory. Las medidas en el doc. han demostrado que la distribución de caracteres del flyweight es absolutamente eficaz. En un caso típico, un documento que contenía 180.000 caracteres requirió la asignación de solamente 480 objetos del carácter.
12. PATRONES ASOCIADOS
Se le relaciona al patrón composite frecuentemente con los patrones; composite, state, strategy, abstract factory.
REFERENCIAS BIBLIOGRÁFICAS
Design Patterns. Elements of Reusable Object-Oriented Software - Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides - Addison Wesley (GoF- Gang of Four)
Thinking in patterns in java – Bruce Eckel
Patterns in Java - Mark Grand – Wiley